【问题标题】:How to define alternate XML structures in XSD schema?如何在 XSD 模式中定义备用 XML 结构?
【发布时间】:2011-06-10 20:05:36
【问题描述】:

如何在 xsd 模式中定义备用 XML 结构?例如,下一个结构是可选的:

<a>
  <b/>
  <c>
    <d/>
  </c>
</a>

<a>
  <c>
    <e/>
  </c>
</a>

在第一种情况下,如果在“c”元素下找到“d”元素,则必须有“b”元素。在第二种情况下,如果“c”下有“e”,则不允许有“b”元素。所以我正在寻找这种解决方案:

<xsd:element name="a">
    <xsd:complexType>
        <xsd:all>

(

            <xsd:element name="b" type="whatever"/>
            <xsd:element name="c">
                <xsd:complexType>
                    <xsd:all>
                        <xsd:element name="d" type="whatever"/>
                    </xsd:all>
                </xsd:complexType>
            </xsd:element> )

) 或 (

            <xsd:element name="c">
                <xsd:complexType>
                    <xsd:all>
                        <xsd:element name="e" type="whatever"/>
                    </xsd:all>
                </xsd:complexType>
            </xsd:element>

)

        </xsd:all>
    </xsd:complexType>
</xsd:element>

我不想使用选择元素的原因是因为我正在为 XML 文档制作一个编辑器界面,而在我的例子中,选择在编辑器界面中看起来很愚蠢。

【问题讨论】:

  • &lt;xs:choice&gt;for“选择”。这就是它的目的。
  • 嗯。你现在就是我想的。我必须以不同的方式做这件事。
  • 但是您如何对整个结构进行选择呢?我的意思是会有不止一个元素作为选项。第一个选择包括 b 和 c,第二个选择只包括 c。我的意思是我不想将 b 和 c 包含在第三个元素中。
  • 看起来我可以使用组元素:w3schools.com/schema/el_group.asp
  • 好的,实际上我必须在组元素内有一个序列元素,或者只有没有组的序列。因此,选择元素将仅包含序列元素,其中第一个元素将包含 b 和 c(将包含 d),第二个将包含 c(将包含 e)。呸。顺便说一句:选择元素不能包含 all 元素(这将允许我的 b 和 c 以任何顺序排列)有什么合理的理由吗?

标签: xml xsd schema


【解决方案1】:

解决方案是定义两个复杂类型来表示结构的每个“状态”。每种复杂类型都会对其中的嵌套元素应用不同的约束。然后您可以简单地将这两种复杂类型分组为 xs:choice 下的项目

类似

<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://NS.Schema1" targetNamespace="http://NS.Schema1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="structure">
          <xs:complexType>
            <xs:choice minOccurs="1" maxOccurs="1">
              <xs:element name="a1" type="a1" />
              <xs:element name="a2" type="a2" />
            </xs:choice>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="a1">
    <xs:sequence>
      <xs:element name="b" type="xs:string" />
      <xs:element name="c">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="d" type="xs:string" />
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="a2">
    <xs:sequence>
      <xs:element name="c">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="e" type="xs:string" />
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

但是,两种复杂类型的根元素名称不能相同。

【讨论】:

    【解决方案2】:

    我有点借用 thecolour 的答案。我的意思是我不希望我的选择结构位于元素内部。

    有了 thecolour 的回答,这样的文件就可以工作了:

    <?xml version="1.0"?>
    <Root>
    <structure>
    <a1>
    <b>jkhgjhg</b>
    <c>
    <d>asdf</d>
    </c>
    </a1>
    </structure>
    </Root>
    

    但是下一个模式按我想要的方式工作(thecolour 的答案也有那个额外的“结构”元素。我正在跳过它。):

    <?xml version="1.0" encoding="utf-8"?>
    <xs:schema xmlns="http://NS.Schema1" targetNamespace="http://NS.Schema1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:element name="Root">
        <xs:complexType>
           <xs:choice minOccurs="1" maxOccurs="1">
              <xs:sequence>
                 <xs:element name="b" type="xs:string" />
                 <xs:element name="c">
                    <xs:complexType>
                       <xs:all>
                          <xs:element name="d" type="xs:string" />
                       </xs:all>
                    </xs:complexType>
                 </xs:element>
              </xs:sequence>
              <xs:sequence>
                 <xs:element name="c">
                    <xs:complexType>
                       <xs:all>
                          <xs:element name="e" type="xs:string" />
                       </xs:all>
                    </xs:complexType>
                 </xs:element>
              </xs:sequence>
           </xs:choice>
        </xs:complexType>
      </xs:element>
    </xs:schema>
    

    这有一个缺点,即在第一选择中,“b”和“c”元素必须按此顺序排列。我不知道为什么“选择”中不能有“全部”指示符。可能是因为模式解析器在内部是如何工作的???

    使用这种架构 XML 文档,这样可以工作:

    <?xml version="1.0"?>
    <Root>
    <b>jkhgjhg</b>
    <c>
    <d>asdf</d>
    </c>
    </Root>
    

    【讨论】:

      猜你喜欢
      • 2014-10-08
      • 2011-01-27
      • 2021-07-17
      • 2012-07-26
      • 2021-12-17
      • 2021-10-15
      • 1970-01-01
      • 1970-01-01
      • 2014-05-19
      相关资源
      最近更新 更多