仅将名称空间前缀添加到根元素?

时间:2016-09-05 07:33:09

标签: java xml xsd jaxb moxy

我有一个XSD,我使用xjc从中生成我的Java类。

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;

我策划这个对象:

<?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>

在这里,我只希望我的根元素具有 abc前缀(abc:student)。

我编组如:

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

所以我在我的元素中加上abc前缀。

然而,当我解散时,我得到例外:

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)

我知道这个异常会被抛出,因为它期望一个没有abc前缀的元素(abc:student)。

因此,如果我在@XmlRootElement中添加名称空间,例如:

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

}

不抛出此异常。现在我有很多这样的模型类都在同一个包中。我想在@XmlRootElement中添加名称空间

我不想手动编辑这么多类。

有没有办法将名称空间添加到包中的所有@XmlRootElements

或者我做错了什么?

如何只为根元素添加前缀? 如果我在 package-info 中添加名称空间,则所有元素都会获得前缀 abc ,这是我不想要的。

@XmlSchema(
        elementFormDefault=XmlNsForm.QUALIFIED,
        namespace="http://example.com/xml/protocols"  
        xmlns={@XmlNs(prefix="abc", 
                      namespaceURI="http://example.com/xml/protocols")}
    )

1 个答案:

答案 0 :(得分:0)

我认为你不清楚XML namespace。元素<student>根据default namespacexsd中定义,abc:namespace中的子元素位于namespace。但是,如果在@XMLRootElement中添加abc,则意味着您将覆盖xsd,并且相应的JAXB类对xsd不再有效。

因此,如果您只想将<student>命名空间添加到 <xs:element name="abc:student"> ,可以按照以下方式将其添加到xsd中

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>

input