代码之家  ›  专栏  ›  技术社区  ›  Mark H

如何为具有引用约束的无序XML节点列表创建架构

  •  16
  • Mark H  · 技术社区  · 15 年前

    对于这样的XML布局,我正试图创建一个XSD模式来验证它。

    <RootNode>
      <ChildA />
      <ChildC />
      <ChildB />
      <ChildB />
      <ChildA />
    </RootNode>
    

    要求如下:

    • 可能出现Childa、Childb和Childc 以任何顺序 . ( <xs:sequence> 不合适的)
    • ChildA是 强制性的 但可能会发生多次。
    • childb是可选的,可能出现多次。
    • CHILDC是可选的,可能会发生 只一次 .

    我通常用于创建无序节点列表的技术是使用 <xs:choice maxOccurs="unbounded"> 但是,对于列表中的每个可能节点,我无法创建 minOccurs="1" 对Childa和 maxOccurs="1" 儿童禁忌症。(选择发生的事件优先于此处的元素)。

    <xs:element name="RootNode">
      <xs:complexType>
        <xs:choice minOccurs="1" maxOccurs="unbounded">
          <xs:element name="ChildA" minOccurs="1"/>
          <xs:element name="ChildB" />
          <xs:element name="ChildC" maxOccurs="1"/>
        </xs:choice>
      </xs:complexType>
    </xs:element>
    
    3 回复  |  直到 7 年前
        1
  •  11
  •   Flow Matt McDonald    7 年前

    更新 :在XSD 1.1M中,对 all -小组已经被解除。看答案 here here .

    不简单,但似乎可行。这里的难点在于模式定义必须是确定性的。我使用的方法是通过绘制问题的有限状态自动机来可视化问题,然后编写与该自动机对应的正则表达式。它根本不像听起来那么复杂。不过,使用其他验证系统可能会提供更简单的答案。

    我做了一些测试,但是遗漏了一些特殊的情况很容易。如果你发现一个错误,请发表评论。

    ……代码如下:

    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
    
        <!-- Schema for elements ChildA, ChildB and ChildC
            The requirements are as follows:
                * ChildA, ChildB and ChildC may occur in any order.
                * ChildA is mandatory but may occur multiple times.
                * ChildB is optional and may occur multiple times.
                * ChildC is optional and may occur once only.
        -->
    
        <xsd:element name="root">
            <xsd:complexType>
                <xsd:sequence>
                    <xsd:element name="ABC-container" type="ABC" maxOccurs="unbounded"/>
                </xsd:sequence>
            </xsd:complexType>
        </xsd:element>
    
        <xsd:complexType name="ABC">
            <xsd:sequence>
                <xsd:element name="ChildB" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
                <xsd:choice>
                    <xsd:sequence maxOccurs="1">
                        <xsd:element name="ChildC" type="xsd:string"/>
                        <xsd:element name="ChildB" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
                        <xsd:element name="ChildA" type="xsd:string"/>
                        <xsd:sequence minOccurs="0" maxOccurs="unbounded">
                            <xsd:element name="ChildA" type="xsd:string" minOccurs="0"/>
                            <xsd:element name="ChildB" type="xsd:string" minOccurs="0"/>
                        </xsd:sequence>
                    </xsd:sequence>
                    <xsd:sequence maxOccurs="1">
                        <xsd:element name="ChildA" type="xsd:string" minOccurs="1"/>
                        <xsd:sequence minOccurs="0" maxOccurs="unbounded">
                            <xsd:element name="ChildA" type="xsd:string" minOccurs="0"/>
                            <xsd:element name="ChildB" type="xsd:string" minOccurs="0"/>
                        </xsd:sequence>
                        <xsd:sequence minOccurs="0" maxOccurs="1">
                            <xsd:element name="ChildC" type="xsd:string"/>
                            <xsd:sequence minOccurs="0" maxOccurs="unbounded">
                                <xsd:element name="ChildA" type="xsd:string" minOccurs="0"/>
                                <xsd:element name="ChildB" type="xsd:string" minOccurs="0"/>
                            </xsd:sequence>
                        </xsd:sequence>
                    </xsd:sequence>
                </xsd:choice>
            </xsd:sequence>
        </xsd:complexType>
    
    </xsd:schema>
    
        2
  •  2
  •   karakfa    13 年前

    这应该按照您指定的方式进行:

    <xs:element name="RootNode">   
      <xs:complexType>     
        <xs:all>       
          <xs:element name="ChildA" minOccurs="1"/>      
          <xs:element name="ChildB" />       
          <xs:element name="ChildC" minOccurs="0" maxOccurs="1"/>     
        </xs:all>   
      </xs:complexType> 
    </xs:element> 
    
        3
  •  1
  •   Texas    13 年前

    我只是在读 relax-NG shortcut syntax .

    我猜想,在RELAXNG的紧凑语法中,这将浓缩为以下内容:

    head = element root { ChildA & ChildC? & ChildB* }
    

    那当然很漂亮。