【问题标题】:Multi-Namespace XML Document with no prefixes没有前缀的多命名空间 XML 文档
【发布时间】:2014-11-17 19:15:17
【问题描述】:

我有一个有趣的情况,我的 XML 编辑器(Oxygen,它使用 Xerces XML 处理器)需要根标记上的前缀,但我的 JAXB XML Marshaller(也基于 Xercies)不需要根标记上的前缀。我正在尝试了解这种情况。

首先是 2 个架构文件:

ns1.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://www.ns1.com"
    xmlns="http://www.ns1.com"
    xmlns:ns2="http://www.ns2.com"
    elementFormDefault="unqualified"
    attributeFormDefault="unqualified"
    version="1.0" >
    <xs:import namespace="http://www.ns2.com" schemaLocation="ns2.xsd"/>
    <xs:element name="root"> 
        <xs:complexType>
            <xs:all>
                <xs:element name="element1">
                    <xs:complexType>
                        <xs:all> 
                            <xs:element name="element1a" type="NS1Type"/>
                            <xs:element name="element1b" type="ns2:NS2Type"/>
                        </xs:all>
                    </xs:complexType>
                </xs:element>
            </xs:all>
        </xs:complexType>
    </xs:element>
    <xs:simpleType name="NS1Type">
        <xs:restriction base="xs:string">
            <xs:enumeration value="VALUE_1"/>
        </xs:restriction>
    </xs:simpleType>
</xs:schema>

ns2.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://www.ns2.com"
    xmlns="http://www.ns2.com"
    elementFormDefault="unqualified"
    attributeFormDefault="unqualified"
    version="1.0" >

    <xs:complexType name="NS2Type">
        <xs:all>
            <xs:element name="value" type="xs:float" minOccurs="0"/>
        </xs:all>
    </xs:complexType>
</xs:schema>

当前版本的 Oxygen (16.1) 需要我称之为“版本 1”的内容

版本 1

<?xml version="1.0" encoding="UTF-8"?>
<ns1:root 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:ns1="http://www.ns1.com"
 xsi:schemaLocation="http://www.ns1.com ../schema/ns1.xsd">
    <element1>
        <element1a>VALUE_1</element1a>
        <element1b>
            <value>4.5</value>
        </element1b>
    </element1>
</ns1:root>

如果我像这个例子一样删除前缀(版本 1):

第 2 版

<?xml version="1.0" encoding="UTF-8"?>
<root 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:ns1="http://www.ns1.com"
 xsi:schemaLocation="http://www.ns1.com ../schema/ns1.xsd">
    <element1>
        <element1a>VALUE_1</element1a>
        <element1b>
            <value>4.5</value>
        </element1b>
    </element1>
</root>

氧气抱怨:

“[Xerces] cvc-elt.1.a:找不到元素'root'的声明。”

另一方面,JAXB 仅适用于版本 2。如果我提供版本 1,我会收到此错误:

javax.xml.bind.UnmarshalException:意外元素(uri:“http://www.ns1.com”,本地:“root”)。预期元素是

完整的堆栈跟踪是:

at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:662)
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:258)
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:253)
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:120)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1063)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:498)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:480)
    at com.sun.xml.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:150)
    at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
    at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
    at org.apache.xerces.impl.XMLNSDocumentScannerImpl$NSContentDispatcher.scanRootElementHook(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.DTDConfiguration.parse(Unknown Source)
    at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
    at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)

现在 JAXB 编组器和解组器代码是:

    JAXBContext context = JAXBContext.newInstance(object.getClass());
    javax.xml.bind.Marshaller marshaller = context.createMarshaller();


    JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
    Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

虽然我很快将允许 Swagger Core 进行编组和解组,并且 Swagger 使用 Jackson XML。

我需要弄清楚如何以我的编辑器和我的 JAXB 解组器都接受它的方式构造这个 XML(或配置 JAXB)

【问题讨论】:

    标签: xml jaxb xsd jackson xerces


    【解决方案1】:

    问题不是前缀,而是命名空间

    您的架构有目标命名空间还有elementFormDefault="unqualified"(您确定要这个吗?)。这意味着全局元素是合格的,但本地元素不是。

    所以您的root 元素 合格的并且属于命名空间http://www.ns1.com。所以 Xerces 错误信息是正确的。

    另一个问题是,为什么 JAXB 不能识别命名空间。 A 您没有发布您的 Java 代码(请发布)我有两个理论:

    • 您手动定义了 JAXB 注释,但没有正确定义命名空间。
    • 您已经使用 XJC 或基于此的东西生成了代码,但不知何故错过了通常定义前缀的 package-info.java

    顺便说一句,我不会将任何 JAXB 实现称为“基于 Xerces”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 2022-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多