XML unmarshalling using Jaxb with namespaces and schema

走远了吗. 提交于 2019-12-23 20:15:04

问题


I have an XML document that looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<xs:msgdata xmlns:xs="http://www.myCompany.com" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://www.myCompany.com msgdata.xsd">
  <xs:msgid>MsgID001</xs:msgid>
  <xs:msgHash>hlkJKLHljkhkjlHKJLHkjl6y987HJKH</xs:msgHash> 
</xs:msgdata>

A schema document (called msgdata.xsd) was also sent to me. I am using JAXB to unmarshall the above xml document to a Java object. The unmarshalling code is shown below:

final JAXBContext context = JAXBContext.newInstance(clazz);
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(new File("C:\\temp\\msgdata.xsd"));

final Unmarshaller unmarshaller = context.createUnmarshaller();
unmarshaller.setSchema(schema);

return (T) unmarshaller.unmarshal(new StringReader(xml));  

The target object for the XML is shown below (The object is then converted to a hibernated entity.

@XmlRootElement(name = "msgdata")
public class Message {

    private     String  msgid;
    private     String  msgHash;

    @XmlElement(name = "msgid")
    public String getMsgid() {
        return msgid;
    }

    public void setMsgid(String msgid) {
        this.msgid = msgid;
    }

    @XmlElement(name = "msgHash")
    public String getMsgHash() {
        return msgHash;
    }
    public void setMsgHash(String msgHash) {
        this.msgHash = msgHash;
    }

A couple of questions:

  • I have a rest service where i will receive an XML document in the format shown above. What is the reference for the schema document. I know that the schema document is used for validating the XML document. I think the way it will work is that i use that schema to validate the XML documents that i receive via the REST service. Now the problem is how do i access the schema? Do i just store it somewhere on my file system and access it as shown above?

The XML document has a reference to the schema (See the schemaLocation entry). How will it find the schema document on my file system? Is that schema reference required in the XML document?

  • The XML document as it is now cannot be unmarshalled. When i try to unmarshal it i get the following error:

    Caused by: javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.myCompany.com", local:"msgdata"). Expected elements are <{}msgdata> at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:662) [jaxb-impl-2.2.4.jar:] at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:258) [jaxb-impl-2.2.4.jar:] at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:253) [jaxb-impl-2.2.4.jar:] at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:120) [jaxb-impl-2.2.4.jar:] at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1063) [jaxb-impl-2.2.4.jar:] at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:498) [jaxb-impl-2.2.4.jar:] at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:480) [jaxb-impl-2.2.4.jar:] at com.sun.xml.bind.v2.runtime.unmarshaller.ValidatingUnmarshaller.startElement(ValidatingUnmarshaller.java:102) [jaxb-impl-2.2.4.jar:] at com.sun.xml.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:150) [jaxb-impl-2.2.4.jar:] at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source) [xercesImpl-2.9.1.jar:] at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source) [xercesImpl-2.9.1.jar:] at org.apache.xerces.impl.XMLNSDocumentScannerImpl$NSContentDispatcher.scanRootElementHook(Unknown Source) [xercesImpl-2.9.1.jar:] at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source) [xercesImpl-2.9.1.jar:] at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) [xercesImpl-2.9.1.jar:] at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) [xercesImpl-2.9.1.jar:] at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) [xercesImpl-2.9.1.jar:] at org.apache.xerces.parsers.XMLParser.parse(Unknown Source) [xercesImpl-2.9.1.jar:] at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source) [xercesImpl-2.9.1.jar:] at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source) [xercesImpl-2.9.1.jar:] at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:217) [jaxb-impl-2.2.4.jar:] at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:189) [jaxb-impl-2.2.4.jar:] at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:136) [jboss-jaxb-api_2.2_spec-1.0.3.Final.jar:1.0.3.Final] at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:193) [jboss-jaxb-api_2.2_spec-1.0.3.Final.jar:1.0.3.Final] ... 31 more

I thought the namespace is defined in the xml document. I am either not using the schema correctly or the namespace definition is not correct. What am i doing wrong?

Thanks.


回答1:


In general, for how to access files (XSD or others) in your Java web application (since you mentioned REST), you could start here. Never rely on absolute paths, for deployment as well as security reasons.

The xsi schema location attributes are just hints; they are not required. Even if present those don't have to be considered. For a server side application, I would never use them anyway; one should rely on embedded resources, or use a catalog-like concept at a trusted/secure location.

The fact that it doesn't unmarshal, is clear in the error message: it expects a no-namespace element <{}msgdata> as opposed to <{http://www.myCompany.com}msgdata>.

You need to modify the XML or ammend your class to include things like @XmlElement(name="...", namespace="http://www.myCompany.com")

I would say that given schema and XML are correct, your annotations are not in sync.



来源:https://stackoverflow.com/questions/9295194/xml-unmarshalling-using-jaxb-with-namespaces-and-schema

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!