3

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.

ziggy
  • 15,677
  • 67
  • 194
  • 287
  • The following may help: http://blog.bdoughan.com/2010/08/jaxb-namespaces.html and http://blog.bdoughan.com/2010/12/jaxb-and-marshalunmarshal-schema.html – bdoughan Feb 15 '12 at 14:43
  • Does the schema put the elements in the namespaces you're expecting? Post the schema if you want ;] – davidfrancis Feb 15 '12 at 15:37
  • I am using JAXB to unmarshall the xml i.e. convert from XML to a java object not the other way round. Thanks – ziggy Feb 15 '12 at 19:01

1 Answers1

9

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.

Community
  • 1
  • 1
Petru Gardea
  • 21,373
  • 2
  • 50
  • 62
  • Do i need to specify the namespace with the annotations? – ziggy Feb 15 '12 at 18:24
  • Yes, please use @ XmlElement or @ XmlRootElement with name and namespace: (name="...", namespace="http://www.myCompany.com") – Petru Gardea Feb 15 '12 at 18:38
  • I tried that and it looks like i need to specify the namespace on each field as well. Is there any way i can specify the namespace globally? – ziggy Feb 15 '12 at 21:25
  • 3
    I would use the [@XmlSchema](http://docs.oracle.com/javase/6/docs/api/javax/xml/bind/annotation/XmlSchema.html) annotation at the package level. It would look like this: @javax.xml.bind.annotation.XmlSchema(namespace="http://www.myCompany.com", elementFormDefault=javax.xml.bind.annotation.XmlNsForm.QUALIFIED) package com.mypackage; – Petru Gardea Feb 15 '12 at 22:25