如何在属性中定义具有不同值的2个元素?

时间:2013-11-08 08:55:38

标签: xml xsd xsd-validation

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

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

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

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

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

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

请帮忙。 谢谢。

2 个答案:

答案 0 :(得分: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>

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

<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)可替代它。因此,红色和绿色名称元素之间的关系反映在替换组关系中。

答案 1 :(得分:0)

在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>