Jaxb: How to Ignore Namespace During Unmarshalling Xml Document

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



Leave a reply



Submit