Java – unmarshalling with multiple namespaces
So, suppose I have several namespaces of XML
<Envelope xmlns:pdi="http://www.mypage.com/schemas/pdi" xmlns:ib="http://www.mypage.com/schemas/ib" xmlns="http://www.mypage.com/schemas/envelope"> <Product> <pdi:number>123456</pdi:number> </Product> <Instance> <ib:serial>abcdefg</ib:serial> </Instance> </Envelope>
I'm trying to build a client for it I have an envelope POJO like this
@XmlRootElement(name ="Envelope",namespace = "http://www.mypage.com/schemas/envelope") public class Envelope
Inside, it has these properties
@XmlElement(name="Product",namespace = "http://www.mypage.com/schemas/pdi") public Product getProduct(){...} @XmlElement(name="Instance",namespace = "http://www.mypage.com/schemas/ib") public Instance getInstance(){...}
In addition, the product POJO is as follows:
@XmlRootElement(name="Product",namespace = "http://www.mypage.com/schemas/pdi") public class Product
And properties
@XmlElement(name="pdi:number",namespace = "http://www.mypage.com/schemas/pdi") public int getNumber(){...}
For some reason, I can't get the product number I keep getting requests wrong Do I handle namespaces correctly, or do I miss something?
Solution
For this use case, I recommend using package level @ XMLSchema annotation to specify namespace qualification
package-info(forum14651918 / package-info.java)
@XmlSchema( namespace="http://www.mypage.com/schemas/envelope",elementFormDefault=XmlNsForm.QUALIFIED,xmlns={ @XmlNs(namespaceURI = "http://www.mypage.com/schemas/envelope",prefix = ""),@XmlNs(namespaceURI = "http://www.mypage.com/schemas/ib",prefix = "ib"),@XmlNs(namespaceURI = "http://www.mypage.com/schemas/pdi",prefix = "pdi") } ) @XmlAccessorType(XmlAccessType.FIELD) package forum14651918; import javax.xml.bind.annotation.*;
Envelope (forum14651918 / envelope. Java)
Since we specified the namespace and elementformdefault on the @ XMLSchema annotation, we will use http://www.mypage.com/schemas/envelope The namespace automatically qualifies all elements corresponding to the envelope class
package forum14651918; import javax.xml.bind.annotation.*; @XmlRootElement(name="Envelope") public class Envelope { @XmlElement(name="Product") private Product product; @XmlElement(name="Instance") private Instance instance; }
Product (forum14651918 / product. Java)
You can override the namespace of the product class with the @ xmltype annotation
package forum14651918; import javax.xml.bind.annotation.*; @XmlType(namespace="http://www.mypage.com/schemas/pdi") public class Product { private int number; }
Instance (forum14651918 / instance. Java)
You can override the namespace of the instance class with the @ xmltype annotation
package forum14651918; import javax.xml.bind.annotation.XmlType; @XmlType(namespace="http://www.mypage.com/schemas/ib") public class Instance { private String serial; }
Demo (forum14651918 / demo. Java)
Here are some code that you can run to prove that everything is normal
import java.io.File; import javax.xml.bind.*; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Envelope.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); File xml = new File("src/forum14651918/input.xml"); Envelope envelope = (Envelope) unmarshaller.unmarshal(xml); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true); marshaller.marshal(envelope,System.out); } }
For more information
> http://blog.bdoughan.com/2010/08/jaxb-namespaces.html > http://blog.bdoughan.com/2011/11/jaxb-and-namespace-prefixes.html > http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html