当架构有elementFormDefault =“unqualified”时,为什么我不能在xml实例中使用默认命名空间?

时间:2017-09-11 12:53:00

标签: java xml xsd jaxb

我有一个带有targetNamespace和非限定元素形式默认的模式:

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://shiporder.hu/Shiporder" 
    xmlns="http://shiporder.hu/Shiporder"
    elementFormDefault="unqualified">
    <xs:complexType name="shipordertype">
        <xs:sequence>
            <xs:element name="orderid" type="xs:string" />
        </xs:sequence>
    </xs:complexType>
    <xs:element name="shiporder" type="shipordertype" />
</xs:schema>

我不明白为什么以下实例无效:

<?xml version="1.0" encoding="UTF-8"?>
<shiporder 
xmlns="http://shiporder.hu/Shiporder" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://shiporder.hu/Shiporder shiporder_unqualified.xsd">
  <orderid>123456</orderid>
</shiporder>

Jaxb验证说“无效内容是从元素'orderid'开始的。预计会有一个'{orderid}'”我对此感到特别困惑消息,如果预期“orderid”,那么“orderid”有什么问题?

这是验证错误:

org.xml.sax.SAXParseException; systemId:file:/home/riskop/git/xml_schema_elementformdefault_question/src/main/resources/order_unqualified_with_default_ns.xml; lineNumber:6; columnNumber:12; cvc-complex-type.2.4.a:从元素'orderid'开始发现无效内容。预计有一个'{orderid}'。     at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203)     在......

我在github上有一个小小的演示:

https://github.com/riskop/xml_schema_elementformdefault_question.git

3 个答案:

答案 0 :(得分:2)

如果不是只是告诉你它的期望,那么你可以更容易地看到发生了什么,验证者也告诉过你发现了什么。

您的架构声明扩展名为{http://shiporder.hu/Shiporder}shiporder的任何元素都是{http://shiporder.hu/Shiporder}shipordertype类型。与该类型的所有元素一样,它被声明为只有一个子节点,其扩展名称为{}orderid。 (或者,在您的验证器{orderid}显然使用的表示法中。)

实例中的外部元素具有扩展名{http://shiporder.hu/Shiporder}shiporder,但它不遵守约束:它具有单个子元素,但该子元素具有扩展名{http://shiporder.hu/Shiporder}orderid。 (或者,您的验证人明确使用的符号http://shiporder.hu/Shiporder{orderid}

如果您希望您的实例看起来像这个示例实例,最简单的解决方法是将elementFormDefault更改为'qualified'。但您也可以将实例更改为

<?xml version="1.0" encoding="UTF-8"?>
<shiporder 
  xmlns="http://shiporder.hu/Shiporder" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://shiporder.hu/Shiporder 
  shiporder_unqualified.xsd">
    <orderid xmlns="">123456</orderid>
</shiporder>

如果您对刚才给出的解释的反应不过是“D'哦!”,那么您可能需要查看术语“[namespace-] qualified”和“[namespace-]”的含义。不合格的“以及默认和其他名称空间声明的含义。

答案 1 :(得分:0)

请尝试以下其中一个实例:

y

<shiporder 
    xmlns="http://shiporder.hu/Shiporder"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://shiporder.hu/Shiporder shiporder_unqualified.xsd">
    <orderid>123456</orderid>
</shiporder>

<q:shiporder xmlns:q="http://shiporder.hu/Shiporder" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://shiporder.hu/Shiporder shiporder_unqualified.xsd"> <q:orderid>123456</q:orderid> </q:shiporder> 没有按照你的想法行事;见例如。 What does elementFormDefault do for XML/When is it used?获得解释。

答案 2 :(得分:0)

McQueen的回答很有启发性,谢谢!

我想总结一下这个和我的理解:

  1. 将elementFormDefault =&#34;不合格&#34;在架构中指定了两件事:
    1. 全局声明的元素必须在实例中显式限定。
    2. 本地声明的元素在实例中不得限定。
  2. 元素&#34; orderid&#34;是模式中本地声明的元素,因此&#34; orderid&#34;在实例中不得有资格
  3. 元素&#34; shiporder&#34;在实例中指定了一个默认命名空间,因此所有它的子元素都将被限定,因此&#34; orderid&#34;在实例中是合格的,这与上面的第2点相矛盾
  4. 这回答了我的问题。

    我仍然认为JAXB验证消息令人费解并且含糊不清:&#34;从元素&#39; orderid&#39;开始发现无效内容。其中一个{orderid}&#39;预期。&#34; 。 &#39; {订单ID}&#39;并不像表达&#39; {} orderid&#39;会是,而且我也错过了消息中的实际元素。我希望看到类似的内容:&#34;无效内容从&#39; orderid开始:&#39;:实际:&#39; {http://shiporder.hu/Shiporder} orderid&#39;&#34; ,预期:&#39; {} orderid&#39;。这基本上是McQueen在回答中首先说的。

    无论如何,实例中的可能修复是在&#34; orderid&#34;中取消定义名称空间。元素(<orderid xmlns="">):

    <q:shiporder 
        xmlns:q="http://shiporder.hu/Shiporder"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://shiporder.hu/Shiporder shiporder_unqualified.xsd">
        <orderid >123456</orderid>
    </q:shiporder>
    

    或不使用默认命名空间:

    <q:shiporder 
        xmlns:q="http://shiporder.hu/Shiporder"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://shiporder.hu/Shiporder shiporder_unqualified.xsd">
        <orderid >123456</orderid>
    </q:shiporder>
    

    架构中的可能修复方法是将其更改为限定:

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://shiporder.hu/Shiporder" 
        xmlns="http://shiporder.hu/Shiporder"
        elementFormDefault="qualified">
        <xs:complexType name="shipordertype">
            <xs:sequence>
                <xs:element name="orderid" type="xs:string" />
            </xs:sequence>
        </xs:complexType>
        <xs:element name="shiporder" type="shipordertype" />
    </xs:schema>
    

    或更改为global declarations(&#34;不合格&#34;对全局声明的元素没有影响,在这种情况下&#34; orderid&#34;全局声明以及&#34;运送订单&#34):

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://shiporder.hu/Shiporder" 
        xmlns="http://shiporder.hu/Shiporder"
        elementFormDefault="unqualified">
        <xs:complexType name="shipordertype">
            <xs:sequence>
                <xs:element ref="orderid" />
            </xs:sequence>
        </xs:complexType>
        <xs:element name="shiporder" type="shipordertype" />
        <xs:element name="orderid" type="xs:string" />
    </xs:schema>
    

    ...

    请注意,我同意Michael Kay指定&#34;合格&#34;对于架构中的elementFormDefault来说,几乎总是正确的做法......