1

I have a XSD from which I generate my Java classes using xjc.

XSD:

<xs:schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://example.com/xml/protocols"
    xmlns:abc="http://example.com/xml/protocols" elementFormDefault="unqualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="student">
        <xs:complexType>
            <xs:complexContent>
                <!-- Inherit common attributes from Regular Type -->
                <xs:extension base="abc:regular">
                    <xs:sequence>
                        <!-- Resource Specific Attributes -->
                        <xs:element name="name" type="abc:name" minOccurs="0" />
                        <xs:element name="URI" type="abc:listOfURIs" />

                        <xs:element name="content" type="abc:content" />


            </xs:complexContent>
        </xs:complexType>
    </xs:element>

Student.java:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "eventNotificationCriteria",
    "notificationURI",
    "notificationContentType"
})
@XmlRootElement(name = "student")
public class Student
    extends Regular
{

    protected Name name;
    @XmlList
    @XmlElement(required = true)
    protected List<String> URI;

    @XmlElement(required = true)
    protected BigInteger content;
.........
}   

package-info.java

@XmlSchema(
    elementFormDefault=XmlNsForm.QUALIFIED,
    xmlns={@XmlNs(prefix="abc", 
                  namespaceURI="http://example.com/xml/protocols")}
)
package package.com;
import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;

I marshall this object to get:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<abc:student xmlns:abc="http://www.example.com/xml/protocols">
    <name>
        <firstname>Jack</firstname>
    </name
    <URI>http://192.168.100.213:8090/S0</URI>
    <content>1</content>
</abc:student>

Here I want only my root elements to have abc prefix (abc:student).

I marshal like:

  marshaller.marshal(new JAXBElement<Student>(new QName("http://example.com/xml/protocols", "student", "abc"), Student.class, (Student)object), outputStream);

So I add abc prefix to my element.

However when I unmarshall I get exception:

javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.example.com/xml/protocols", local:"student"). Expected elements are <{}student>
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:647)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:243)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:238)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:105)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1048)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:483)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:465)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:135)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:506)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:376)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:602)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3116)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:880)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:116)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:511)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:846)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:775)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:123)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1210)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:628)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:203)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:175)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:214)

I know this exception is getting thrown as it's expecting an element without abc prefix (abc:student).

So if I add namespace inside @XmlRootElement like:

    @XmlRootElement(name = "student", namespace="http://example.com/xml/protocols")
    public class Student
        extends Regular{

}

This exception is not thrown. Now I have many such model classes all in same package. I want to add namespace in @XmlRootElement in all these.

I don't want to edit my so many classes manually.

Is there a way to add namespace to all @XmlRootElements in a package ??

Or am I doing something wrong ??

How to add a prefix to only root elements ?? If I add namespace in package-info, all elements get prefix abc which I don't want.

@XmlSchema(
        elementFormDefault=XmlNsForm.QUALIFIED,
        namespace="http://example.com/xml/protocols"  
        xmlns={@XmlNs(prefix="abc", 
                      namespaceURI="http://example.com/xml/protocols")}
    )
Siddharth Trikha
  • 2,648
  • 8
  • 57
  • 101
  • See if this helps: [**Adding namespaces to root element of xml using jaxb**](http://stackoverflow.com/questions/16979762/adding-namespaces-to-root-element-of-xml-using-jaxb) – kjhughes Sep 05 '16 at 13:41
  • @kjhughes: This just add `xmlns:schemaLocation` to root element. I want a prefix to root element like ` ` – Siddharth Trikha Sep 06 '16 at 04:02

1 Answers1

0

I think you are unclear about the XML namespace. The element <student> is defined in default namespace as per your xsd, where as the child elements in abc:namespace. But if you add namespace in the @XMLRootElement then it means you are overwriting the xsd and the corresponding JAXB class is no more valid against the xsd.

So if you want to add namespace abc only to <student>, you can add it in xsd as follows

 <xs:element name="abc:student">

and rest of them in defaultnamespace.

   <xs:element name="abc:student">
        <xs:complexType>
            <xs:complexContent>
                <!-- Inherit common attributes from Regular Type -->
                <xs:extension base="regular">
                    <xs:sequence>
                        <!-- Resource Specific Attributes -->
                        <xs:element name="name" type="name" minOccurs="0" />
                        <xs:element name="URI" type="listOfURIs" />

                        <xs:element name="content" type="content" />


            </xs:complexContent>
        </xs:complexType>
    </xs:element>
ulab
  • 1,079
  • 3
  • 15
  • 45
  • When I generate XML from this XSD in eclipse (Right Click--->generate XML), I get the desried XML with ``, but why is this not the case with first generating JAXB classes and then marshalling ?? – Siddharth Trikha Sep 05 '16 at 10:20
  • It should, you will have to first generate from "this" xsd and marshall it. Post the JAXB to verify. – ulab Sep 05 '16 at 10:48
  • Sorry there was typo (*the not this). I meant from my XSD (not the one you wrote). So from my XSD I get the `` when (Right Click--->generate XML)but this is not the case with first generating JAXB classes and then marshalling. Any idea? – Siddharth Trikha Sep 05 '16 at 10:51
  • When I try what you wrote: I get `s4s-att-invalid-value: Invalid attribute value for 'name' in element 'element'. Recorded reason: cvc- datatype-valid.1.2.1: 'abc:subscription' is not a valid value for 'NCName'.` – Siddharth Trikha Sep 05 '16 at 10:53
  • your intention is not clear to me. And I noticed you have default ` – ulab Sep 05 '16 at 13:07