JAXB: How to ignore namespace during unmarshalling XML document?
I believe you must add the namespace to your xml document, with, for example, the use of a SAX filter.
That means:
- Define a ContentHandler interface with a new class which will intercept SAX events before JAXB can get them.
- Define a XMLReader which will set the content handler
then link the two together:
public static Object unmarshallWithFilter(Unmarshaller unmarshaller,
java.io.File source) throws FileNotFoundException, JAXBException
{
FileReader fr = null;
try {
fr = new FileReader(source);
XMLReader reader = new NamespaceFilterXMLReader();
InputSource is = new InputSource(fr);
SAXSource ss = new SAXSource(reader, is);
return unmarshaller.unmarshal(ss);
} catch (SAXException e) {
//not technically a jaxb exception, but close enough
throw new JAXBException(e);
} catch (ParserConfigurationException e) {
//not technically a jaxb exception, but close enough
throw new JAXBException(e);
} finally {
FileUtil.close(fr); //replace with this some safe close method you have
}
}
Jaxb ignore the namespace on unmarshalling
Namesapce awareness is feature of the document reader/builder/parser not marshallers. XML elements from different namespaces represents different entities == objects, so marshallers cannot ignore them.
You correctly switched off the namespaces in your SAX reader and as you said it worked. I don't understand your problem with it, your marshaller still can be injected, the difference is in obtaining the input data.
The same trick with document builder should also work (I will test it later on), I suspect that you were still using the marshaller with "hardcoded" namespace but your document was namespace free.
In my project I use XSLT to solve similar issue. Setting namespace awarness is definitely easier solution. But, with XSLT I could selectviely remove only some namespaces and also my my input xml are not always identical (ignoring namespaces) and sometimes I have to rename few elements so XSLT gives me this extra flexibility.
To remove namespaces you can use such xslt template:
<xsl:stylesheet version="1.0" xmlns:e="http://timet.dom.robust.ed" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:template match="/">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@* | node()" />
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="text() | processing-instruction() | comment()">
<xsl:copy />
</xsl:template>
</xsl:stylesheet>
Then in Java before unmarshalling I transform the input data:
Transformer transformer = TransformerFactory.newInstance().newTransformer(stylesource);
Source source = new DOMSource(xml);
DOMResult result = new DOMResult();
transformer.transform(source, result);
ignore prefix (namespace) when unmarshalling xml
I am able to do this using StreamReaderDelegate
as mentioned here:
public class XXHeaderXMLReader
extends StreamReaderDelegate
{
public XXHeaderXMLReader(XMLStreamReader paramXMLStreamReader)
{
super(paramXMLStreamReader);
}
@Override
public String getAttributeNamespace(int paramInt)
{
return "";
}
@Override
public String getNamespaceURI()
{
return "";
}
}
and adding the line in previous code:
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
inputFactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, true);
try
{
XMLStreamReader streamReader = inputFactory
.createXMLStreamReader(DocumentTest.class.getClassLoader().getResourceAsStream("xxmsg.xml"));
while (streamReader.hasNext())
{
int next = streamReader.next();
if (streamReader.getEventType() == XMLStreamReader.START_ELEMENT)
{
if (streamReader.getLocalName().equals("Header"))
{
JAXBContext context = JAXBContext.newInstance(XXHeader.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
XXHeaderXMLReader xxHeaderXMLReader = new XXHeaderXMLReader(streamReader);
XXHeader xxHeader =
unmarshaller.unmarshal(xxHeaderXMLReader, XXHeader.class).getValue();
System.out.println(xxHeader);
break;
}
}
}
}
catch (XMLStreamException e)
{
e.printStackTrace();
}
catch (JAXBException e)
{
e.printStackTrace();
}
How to map a XML ignoring namespace using JAXB?
You can map the namespace using the package level @XmlSchema
annotation.
@XmlSchema(
namespace = "http://someurl.com",
elementFormDefault = XmlNsForm.QUALIFIED)
package example;
import javax.xml.bind.annotation.*;
For More Information
I have written more about JAXB and namespace qualification on my blog:
- http://blog.bdoughan.com/2010/08/jaxb-namespaces.html
How to unmarshal XML with multiple namespaces in different xml or ignore namespace in jaxb
I am struggling with JAXB & XJC to build bindings to handle namespaces. I spent a lot of time on forums and googling. It does not works which makes me mad.
Atlast i have found a solution in a blog to ignore the namespace.
here is the solution link
Provided JAXB does not take into account namesapace of xml elements, it wrote the following code in order to ignore namespace while parsing.
JAXBContext jc = JAXBContext.newInstance("com.jmex.model.collada.collada_schema_1_4");
Unmarshaller u = jc.createUnmarshaller();
SAXParserFactory parserFactory;
parserFactory = SAXParserFactory.newInstance();
parserFactory.setNamespaceAware(false);
XMLReader reader = parserFactory.newSAXParser().getXMLReader();
Source er = new SAXSource(reader, new InputSource(sourceStream));
HSIContractInventoryModificationRS hsi = (HSIContractInventoryModificationRS) u.unmarshal(er);
It works, JAXB unmarshalling is successful. (I hope this piece of code can help someone...)
Related Topics
The Difference Between the Runnable and Callable Interfaces in Java
Is a Java String Really Immutable
Specifying Java Version in Maven - Differences Between Properties and Compiler Plugin
Subclassing a Java Builder Class
Can Constructors Throw Exceptions in Java
Quickest Way to Find Missing Number in an Array of Numbers
How to Define a List Bean in Spring
Does a Tcp Socket Connection Have a "Keep Alive"
Converting Many 'If Else' Statements to a Cleaner Approach
Finding Key Associated with Max Value in a Java Map
Serving Static Files from Alternate Path in Embedded Jetty
Java: Reading a File into an Array
Getting Java.Sql.Sqlexception: Operation Not Allowed After Resultset Closed
How to Match String Within Parentheses (Nested) in Java