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

问题描述:

我有一个目标名称和不合格的元素形式默认的模式:为什么我不能在xml实例中使用默认命名空间,当模式具有elementFormDefault =“unqualified”?

<?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}'之一。 在com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203) 在...

我已经在GitHub上一个小演示:

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

如果您不是仅仅告诉您它期望的是什么,而是验证者也告诉您它找到的是什么,那么您会更容易了解发生了什么。

您的模式声明扩展名为{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-]合格”和含义“ [namespace-] unqualified“以及默认和其他名称空间声明的含义。

试试下面的实例,而不是一个:

<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?获得解释。

+0

感谢您的答案!您的第一个实例未通过验证... lineNumber:6; columnNumber:14; cvc-complex-type.2.4.a:从元素'orderid'开始找到无效的内容。预计会有'{orderid}'。“你的第二个实例失败,”... lineNumber:6; columnNumber:16; cvc-complex-type.2.4.a:找到以元素'q:orderid'开头的无效内容。预计会有'{orderid}'之一。“ – riskop

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

我想总结一下,我的理解:在架构

  1. 将elementFormDefault =“不合格”规定了两件事情:
    1. 全局声明的元素必须的情况下,明确合格。
    2. 本地声明的元素不得是限定在实例中。
  2. 元素“订单ID”是在架构中的一个局部声明的元素,因此“订单ID”不能胜任的情况下
  3. 实例中的元素“shiporder”指定默认名称空间,因此它的所有子元素都将被限定,因此实例中的“orderid”是合格的,这与上方的第二点相矛盾。

这回答了我的问题。

我仍然认为JAXB验证信息令人费解并且含糊其辞:“无效的内容是从元素'orderid'开始的,预计会有'{orderid}'之一。。 '{orderid}'不像'{} orderid'那样表达,而且我错过了消息中的实际元素。我希望看到类似这样的内容:“以'orderid'开始的无效内容:actual:'{http://shiporder.hu/Shiporder} orderid'”,预期:'{} orderid'。这基本上是McQueen先生在回答中所说的。

无论如何,在实例可能的修复要么undeclaring命名空间在 “订单ID” 元素(<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> 

or chang E要global declarations(“不合格”没有任何影响全局声明的元素,在这种情况下“订单ID”全局声明以及“运送订单”):

<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的“合格”,几乎总是正确的做...

+1

大致正确,但有点奇怪的措辞。模式定义了一组有效的文档;它没有说你或你的文件必须做或不做任何事情;无论您的文件是有效的还是无效的,都非常高兴。设置elementFormDefault对* all * local元素有影响也是不正确的;默认值可以被覆盖。如果根据架构和文档实例中给出的元素的扩展名称来考虑,则规则更简单:实例元素只有在具有相同(扩展)名称的情况下才与声明匹配。 –