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.