【问题标题】:why I can not use default namespace in an xml instance when the schema has elementFormDefault="unqualified"?当架构具有 elementFormDefault="unqualified" 时,为什么我不能在 xml 实例中使用默认命名空间?
【发布时间】:2018-02-19 17:29:35
【问题描述】:

我有一个带有 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:文件:/home/riskop/git/xml_schema_elementformdefault_question/src/main/resources/order_unqualified_with_default_ns.xml;行号:6;列号:12; cvc-complex-type.2.4.a:发现以元素“orderid”开头的无效内容。需要“{orderid}”之一。 在 com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203) 在...

我在github上有一个小demo:

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

【问题讨论】:

    标签: java xml xsd jaxb


    【解决方案1】:

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

    我想总结一下我的理解:

      架构中的
    1. elementFormDefault="unqualified" 指定了两件事:
      1. 全局声明的元素必须在实例中显式限定。
      2. 本地声明的元素不得在实例中限定。
    2. 元素“orderid”是架构中本地声明的元素,因此在实例中不能限定“orderid”。
    3. 实例中的元素“shiporder”指定了一个默认命名空间,因此它的所有子元素都将是合格的,因此实例中的“orderid”是合格的,这与上面的第二点相矛盾。

    这回答了我的问题。

    我仍然认为 JAXB 验证消息令人费解和神秘:“发现以元素 'orderid' 开头的无效内容。需要 '{orderid}' 之一。”。 “{orderid}”不像“{}orderid”那样表达,而且我也错过了消息中的实际元素。我希望看到类似这样的内容:“从 'orderid' 开始的无效内容:实际:'{http://shiporder.hu/Shiporder}orderid'”,预期:'{}orderid'。这基本上是麦昆在回答中首先说的。

    无论如何,实例中可能的修复是在“orderid”元素(&lt;orderid xmlns=""&gt;)中取消声明命名空间:

    <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(“unqualified”对全局声明的元素没有影响,在这种情况下“orderid”和“shiporder”一样被全局声明):

    <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 的观点,即在架构中为 elementFormDefault 指定“合格”几乎总是正确的做法...

    【讨论】:

    • 大致正确,但措辞有点奇怪。一个模式定义了一组有效的文档;它没有说您或您的文件必须做或不做任何事情;无论您的文件是有效还是无效,我们都非常高兴。设置 elementFormDefault 对 all 本地元素的影响也不完全正确;可以覆盖默认值。如果根据架构和文档实例中给定的元素的扩展名称来考虑,则规则更简单:实例元素仅在它们具有相同(扩展)名称时才匹配声明。
    【解决方案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 更改为“合格”。但您也可以将您的实例更改为

    <?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'oh!”的耳光,您可能需要查看术语“[namespace-]qualified”和“[namespace-] unqualified”以及默认和其他命名空间声明的含义。

    【讨论】:

      【解决方案3】:

      请尝试以下实例之一:

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

      elementFormDefault 不会做你认为它会做的事;见例如。 What does elementFormDefault do for XML/When is it used? 解释一下。

      【讨论】:

      • 感谢您的回答!您的第一个实例使用 ...lineNumber: 6; 验证失败列号:14; cvc-complex-type.2.4.a:发现以元素“orderid”开头的无效内容。需要 '{orderid}' 之一。”您的第二个实例因“...lineNumber: 6; 失败”。列号:16; cvc-complex-type.2.4.a:发现以元素“q:orderid”开头的无效内容。需要 '{orderid}' 之一。"
      猜你喜欢
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 2013-10-16
      • 2013-03-11
      • 1970-01-01
      • 2020-03-04
      • 1970-01-01
      相关资源
      最近更新 更多