【问题标题】:How to define 2 elements with different values in their attributes?如何定义属性中具有不同值的 2 个元素?
【发布时间】:2013-11-08 08:55:38
【问题描述】:

是否可以定义一个可以验证此类 xml 的 xsd 方案:

<test>
  <name Type="1" SomeAttr="value" >
    <info a="1" b="2"/>
  </name>
  <name Type="3" SomeAttr="value" />
</test>

在这个 xml 中可以是 1 或 2 个元素“名称”。

属性“类型”中的第一个元素“名称”只能是 2 个值 - 1 或 2

属性“类型”中的第二个元素“名称”只能是 1 个值 - 3

在 xml 中只能有 1 个子元素“info”,它必须被视为属性值为 1 或 2 的父元素“name”(而不是 Type="3" 的“name”)

请帮忙。 谢谢。

【问题讨论】:

    标签: xml xsd xsd-validation


    【解决方案1】:

    在 XSD 中,作为同一父级的子级出现的任何两个同名元素必须具有相同的类型。 (我在这里省略了一些复杂性;需要完整信息的读者必须查阅规范。)因此,在典型的文档验证中,与元素关联的类型完全由从根的路径决定元素本身的验证集,并且取决于它在其父级的子级中的位置。

    所以:不,您不能为两个同级元素赋予相同的名称和不同的类型。

    如果这两个元素出现在不同的上下文中,它们可以有不同的类型。所以像下面这样的 XML 可以工作:

    <test>
      <context-1>
        <name Type="1" SomeAttr="value" >
          <info a="1" b="2"/>
        </name>
      </context-1>
      <context-2>
        <name Type="3" SomeAttr="value" />
      </context-2>
    </test>
    

    但让两个“名称”元素具有不同类型的最简单方法是给它们不同的名称,以反映它们性质上的差异。

    <test>
      <red-name Type="1" SomeAttr="value" >
        <info a="1" b="2"/>
      </red-name>
      <green-name Type="3" SomeAttr="value" />
    </test>
    

    如果您希望架构以某种方式反映名称的两种形式在某种程度上是同一事物的不同形式,XSD 提供了两种明显的机制:

    • 您可以定义一个name 类型,从中派生出该类型的红色和绿色风味。两种类型之间的关系因此反映在类型层次结构中。

    • 您可以定义一个抽象(或具体!)name 元素并声明两个特定变体(这里称为red-namegreen-name)可以替代它。红色和绿色名称元素之间的关系因此反映在替换组关系中。

    【讨论】:

      【解决方案2】:

      在 Xml Schema 1.1 中,可以使用 xs:alternative,它允许元素根据提供的条件具有不同的类型。

      <xs:element name="name">
          <xs:alternative test="@Type=1" type="name_type_1"/>
          <xs:alternative test="@Type=3" type="name_type_3"/>
      </xs:element>
      

      问题中 XML 的完整架构可能如下所示:

      <?xml version="1.0" encoding="UTF-8"?>
      <xs:schema
              xmlns:xs="http://www.w3.org/2001/XMLSchema"
              xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
              elementFormDefault="qualified"
              attributeFormDefault="unqualified"
              vc:minVersion="1.1">
          <xs:element name="test">
              <xs:complexType>
                  <xs:sequence>
                      <xs:element name="name" minOccurs="0" maxOccurs="unbounded">
                          <xs:alternative test="@Type=1" type="name_type_1"/>
                          <xs:alternative test="@Type=3" type="name_type_3"/>
                      </xs:element>
                  </xs:sequence>
              </xs:complexType>
          </xs:element>
          <xs:complexType name="name_type_1">
              <xs:sequence>
                  <xs:element name="info">
                      <xs:complexType>
                          <xs:attribute name="a"/>
                          <xs:attribute name="b"/>
                      </xs:complexType>
                  </xs:element>
              </xs:sequence>
              <xs:attribute name="Type" type="xs:integer"/>
              <xs:attribute name="SomeAttr"/>
          </xs:complexType>
          <xs:complexType name="name_type_3">
              <xs:attribute name="Type" type="xs:integer"/>
              <xs:attribute name="SomeAttr"/>
          </xs:complexType>
      </xs:schema>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-06-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-20
        • 1970-01-01
        相关资源
        最近更新 更多