mardi 14 avril 2015

Jaxb ignore namespace

I use Jaxb2 and Spring. I am trying to unmarshal some XML that are sent by 2 of my customers.


Up to now, I only had to handle one customer which sent some xml like this :



<foo xmlns="com.acme">
<bar>[...]</bar>
<foo>


that is bound to a POJO like this :



@XmlType(name = "", propOrder = {"bar"})
@XmlRootElement(name = "Foo")
public class Foo {

@XmlElement(name = "Bar")
private String bar;

[...]
}


I discovered that the previous developer hardcoded the namespace in the unmarshaller in order to make it work.


Now, the second customer sends the same XML but changes the namespace!



<foo xmlns="com.xyz">
<bar>[...]</bar>
<foo>


Obviously, the unmarshaller fails to unmarshall because it expects some {com.acme}foo instead of {com.xyz}foo. Unforunately, asking the customer to change the XML is not an option.


What I tried :


1) In application-context.xml, I searched for a configuration which would allow me to ignore the namespace but could not find one :



<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="packagesToScan">
<list>
<value>com.mycompany.mypkg</value>
</list>
</property>
<property name="marshallerProperties">
<map>
<entry key="???"><value type="java.lang.Boolean">false</value></entry>
</map>
</property>
</bean>


it seems that the only available options are the ones listed in the Jaxb2Marshaller's Javadoc :



/**
* Set the JAXB {@code Marshaller} properties. These properties will be set on the
* underlying JAXB {@code Marshaller}, and allow for features such as indentation.
* @param properties the properties
* @see javax.xml.bind.Marshaller#setProperty(String, Object)
* @see javax.xml.bind.Marshaller#JAXB_ENCODING
* @see javax.xml.bind.Marshaller#JAXB_FORMATTED_OUTPUT
* @see javax.xml.bind.Marshaller#JAXB_NO_NAMESPACE_SCHEMA_LOCATION
* @see javax.xml.bind.Marshaller#JAXB_SCHEMA_LOCATION
*/
public void setMarshallerProperties(Map<String, ?> properties) {
this.marshallerProperties = properties;
}


2) I also tried to configure the unmarshaller in the code :



try {
jc = JAXBContext.newInstance("com.mycompany.mypkg");

Unmarshaller u = jc.createUnmarshaller();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(false);//Tried this option.

DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(xmlFile.toFile());
u.unmarshal(new DOMSource(doc));
return (CompositionPlaylist)u.unmarshal(new StreamSource(xmlFile.toFile()));
} catch (ParserConfigurationException | SAXException | IOException | JAXBException e) {
LOGGER.error("Erreur Unmarshalling CPL");
}


It also did not work. Any idea?


Aucun commentaire:

Enregistrer un commentaire