2009-10-30 60 views
4

我有一个XML Schema(xsd文件)片段波纹管,其中我想要NAMEADRESS元素以任何顺序出现,但始终在FILM序列之前。如何获取XML模式中的元素顺序约束?

所以我一直试图做的是这样的:

<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:all>标签不能在同一子级别的其他元素的元素的一部分......但不能找到出路...

有什么建议吗?提前致谢 !

回答

1

好吧,貌似我已经找到一种方法,最终:

<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个元素要做到这一点,你必须指定所有排列...

+0

正确。这个内容模型可以通过分解FILM元素来简化,所以你有一个外部序列,其中包含一个选择,然后是对'FILM'的引用。 – 2012-08-21 01:56:56

3

这是XSD Schema的限制。我将引用自:http://www.w3.org/TR/2001/REC-xmlschema-0-20010502/然后评论:


存在着对一组约束元素第三种选择:该组中的所有元素可能出现一次或根本没有,他们可以以任何顺序出现。所有组(提供SGML &连接器的简化版本)仅限于任何内容模型的顶层。此外,该小组的所有孩子都必须是单个元素(无组),并且内容模型中没有元素可能会出现超过一次,即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> 

根据这一定义,一个comment元素可以选择地出现内purchaseOrder中,它可能之前或任何SHIPTO,收单方后出现和项目元素,但它只能出现一次。此外,所有团体的规定都不允许我们在团体之外宣布诸如评论之类的要素,作为使其不止一次出现的手段。 XML模式规定所有组必须作为内容模型顶部的唯一子项出现。换句话说,下面是非法的: 用非法的例子“所有”集团

<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有一个使用&连接器的更强大的模型,但并不是所有的系统都实现了它。

编辑如果你想在这个水平,你可以使用的Schematron作为模式之后的第二次验证验证XML。它基于XSLT,这种约束更容易表达。

+0

非常感谢您的完整解释。非常有教育意义!事实上,我已经阅读了XSD Schema文档参考的这一部分。现在,我处理我在这里发布的解决方案。 我当然把你的答案标记为有用:) – Clem 2009-10-31 11:49:30