Tuesday, August 26, 2008

How to instruct JAXB to ignore Namespaces

The problem

I am developing an application that accepts Java EE deployment descriptors (XML files) and parses it using JAXB. The application should handle any valid versions of descriptors. The problem here is that the JAXB bean classes are generated in accordance with the latest XSD and the namespace of this XSD may differ from that of the previous versions, resulting in XML parse exception while unmarshalling the xml files.

The Solution

Step 1: Create a new XML SAX filter class by extending the org.xml.sax.helpers.XMLFilterImpl class. The purpose of this class is to set the correct namespace before passing the xml file information to the JAXB unmarshaller.

Step 2: Override the startElement method of XMLFilterImpl class to set the correct namespace. The code snippet of the filter class is shown below:

public class XMLNamespaceFilter extends XMLFilterImpl {
public XMLNamespaceFilter(XMLReader arg0) {
super(arg0);
}
@Override
public void startElement(String uri, String localName,
String qName, Attributes attributes)
throws SAXException {
super.startElement(<required namespace>, localName, qName,
attributes);
}
}





Step 3: Unmarshall the xml document using the following code snippet


JAXBContext jc = JAXBContext.newInstance("ctxpath");
Unmarshaller unmarshaller = jc.createUnmarshaller();

// Create the XMLReader
SAXParserFactory factory = SAXParserFactory.newInstance();
XMLReader reader = factory.newSAXParser().getXMLReader();

// The filter class to set the correct namespace
XMLFilterImpl xmlFilter = new XMLNamespaceFilter(reader);
reader.setContentHandler(unmarshaller.getUnmarshallerHandler());
InputStream inStream = new FileInputStream(new File("some file path"));
SAXSource source = new SAXSource(xmlFilter, new InputSource(inStream));

// Get the root element
JAXBElement rootElement = unmarshaller.unmarshal(source,Some.class);





Summary

The SAX namespace filter did the trick in this case. If you find any better workaround for similar problem, please share it here.










5 comments:

Anonymous said...

Hi ! I like this solution it works for me except , the fields with attributes are ignored ?

Thx , paolo

Anonymous said...

Hi ! I like this solution but the fields i have that have attribute are ignore or missing after the unmarshal !

Thx , paolo

anon_anon said...

you might also want to look at vtd-xml, the latest and most advanced XML processing API available today

http://vtd-xml.sf.net

Anonymous said...

Works like a charm! Thanks!

Anonymous said...

i have same problem, the fields with attributes are ignored. what's work around?