如何在XML模式中获取元素顺序约束?

如何在XML模式中获取元素顺序约束?,xml,xsd,Xml,Xsd,下面是一个XML模式(xsd文件)片段,其中我希望名称和地址元素以任何顺序出现,但总是在电影序列之前 所以我一直在尝试这样做: <xs:element name="ROOM"> <xs:complexType> <xs:all> <xs:element ref="NAME"/> <xs:element ref="ADRESS"/> </xs:all>

下面是一个XML模式(xsd文件)片段,其中我希望
名称
地址
元素以任何顺序出现,但总是在
电影
序列之前

所以我一直在尝试这样做:

  <xs:element name="ROOM">
    <xs:complexType>
      <xs:all>
        <xs:element ref="NAME"/>
        <xs:element ref="ADRESS"/>
      </xs:all>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" ref="FILM"/>
      </xs:sequence>
      <xs:attribute name="group" type="xs:NCName"/>
      <xs:attribute name="typ" use="required" type="xs:NCName"/>
    </xs:complexType>
  </xs:element>

我知道,
标记不能是一个元素的一部分,而其他元素则处于同一子级。。。但是找不到出路


有什么建议吗?提前谢谢

好吧,看来我终于找到了办法:

  <xs:element name="ROOM">
    <xs:complexType>

      <xs:choice>
        <xs:sequence>
          <xs:element ref="NAME"/>
          <xs:element ref="ADRESS"/>
          <xs:element maxOccurs="unbounded" ref="FILM"/>
        </xs:sequence>
        <xs:sequence>
          <xs:element ref="ADRESS"/>
          <xs:element ref="NAME"/>
          <xs:element maxOccurs="unbounded" ref="FILM"/>
        </xs:sequence>
      </xs:choice>

      <xs:attribute name="group" type="xs:NCName"/>
      <xs:attribute name="typ" use="required" type="xs:NCName"/>
    </xs:complexType>
  </xs:element>


但是我假设它不是很优化,考虑到如果你想用10个元素来做这件事,你必须指定所有的排列…

这是XSD模式的一个限制。我将引用:然后评论:


对于约束组中的元素,还有第三个选项:组中的所有元素可能出现一次,也可能根本不出现,并且它们可能以任何顺序出现。all组(提供SGML&-Connector的简化版本)仅限于任何内容模型的顶层。此外,组的子元素必须都是单个元素(无组),并且内容模型中的任何元素都不能出现多次,即minOccurs和maxOccurs的允许值分别为0和1。例如,为了允许purchaseOrder的子元素以任何顺序出现,我们可以将PurchaseOrderType重新定义为: “全体”小组

<xsd:complexType name="PurchaseOrderType">
  <xsd:all>
    <xsd:element name="shipTo" type="USAddress"/>
    <xsd:element name="billTo" type="USAddress"/>
    <xsd:element ref="comment" minOccurs="0"/>
    <xsd:element name="items"  type="Items"/>
  </xsd:all>
  <xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>
<xsd:complexType name="PurchaseOrderType">
 <xsd:sequence>
  <xsd:all>
    <xsd:element name="shipTo" type="USAddress"/>
    <xsd:element name="billTo" type="USAddress"/>
    <xsd:element name="items"  type="Items"/>
  </xsd:all>
  <xsd:sequence>
   <xsd:element ref="comment" minOccurs="0" maxOccurs="unbounded"/>
  </xsd:sequence>
 </xsd:sequence>
 <xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>

根据此定义,注释元素可以选择性地出现在purchaseOrder中,也可以出现在任何shipTo、billTo和items元素之前或之后,但只能出现一次。此外,all组的规定不允许我们在组外声明诸如评论之类的元素,以使其能够多次出现。XML模式规定,所有组必须作为唯一的子组出现在内容模型的顶部。换句话说,以下行为是非法的: “全部”组的非法示例

<xsd:complexType name="PurchaseOrderType">
  <xsd:all>
    <xsd:element name="shipTo" type="USAddress"/>
    <xsd:element name="billTo" type="USAddress"/>
    <xsd:element ref="comment" minOccurs="0"/>
    <xsd:element name="items"  type="Items"/>
  </xsd:all>
  <xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>
<xsd:complexType name="PurchaseOrderType">
 <xsd:sequence>
  <xsd:all>
    <xsd:element name="shipTo" type="USAddress"/>
    <xsd:element name="billTo" type="USAddress"/>
    <xsd:element name="items"  type="Items"/>
  </xsd:all>
  <xsd:sequence>
   <xsd:element ref="comment" minOccurs="0" maxOccurs="unbounded"/>
  </xsd:sequence>
 </xsd:sequence>
 <xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>


我记得当时的讨论是,
xsd:all
如果没有这样的限制,那么建模就太复杂了。它很快扩展到非确定性解析模型。所以限制是0或1,没有兄弟姐妹

SGML有一个更强大的模型,它使用了
&
连接器,但并非所有系统都实现了它


编辑如果希望在此级别验证XML,可以使用Schematron作为模式后的第二个验证器。它基于XSLT,这种类型的约束更容易表达。

非常感谢您的完整解释。很有教育意义!事实上,我已经阅读了XSD模式文档参考的这一部分。现在,我处理我在这里发布的解决方案。我当然认为你的回答很有用:)正确。通过分解
FILM
元素,可以使该内容模型更简洁,因此您有一个外部序列,该序列由一个选项组成,后面是对
FILM
的引用。