XSD具有相同名称但属性值不同的两个元素

时间:2014-03-12 14:34:18

标签: xsd xsd-validation

我正在尝试为以下内容定义XSD模板:

<template_data>
  <given_name lang="ENG">Zluty</given_name>
  <given_name lang="CES">Žlutý</given_name>
</template_data>

到目前为止,我已经提出了

<xs:complexType name="attribute_CES">
  <xs:attribute name="lang" type="xs:string" use="required" fixed="CES"/>
</xs:complexType>

<xs:complexType name="attribute_ENG">
  <xs:attribute name="lang" type="xs:string" use="required" fixed="ENG"/>
</xs:complexType>

<xs:element name="template_data">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="given_name" type="attribute_CES"/>
      <xs:element name="given_name" type="attribute_ENG"/>          
    </xs:sequence>
  </xs:complexType>
</xs:element>

问题是,这定义了一个具有同一个名称的元素两次,每次都有不同的类型,我发现任何XSD验证器都有抗议。

据我所知,您可以要求属性具有fixed选项的特定值,并且包含在(复杂)类型的定义中。因此,如果您希望属性具有不同的值,则必须定义新类型。

我需要的是template_data包含given_name个,只包含lang="CES"一次,而只包含lang="ENG"一次。有没有办法为此编写xsd验证模式,或者这是不可能的(例如,如果xml输入不符合标准)?

1 个答案:

答案 0 :(得分:7)

你不能在同一个上下文中声明两个具有不同类型的相同名称的元素,但我想我明白你想要做什么。

如果你真的拥有内容非常不同的元素,那么创建两种类型是有意义的(并且它们也有意义,它们具有不同的名称或至少出现在另一个上下文中)。由于您的数据类似,主要区别在于描述元素文本内容的属性,因此您可以创建一种类型并限制属性可以接收的值:

<xs:complexType name="languageType">
    <xs:simpleContent>
        <xs:extension base="xs:string">
            <xs:attribute name="lang" use="required">
                <xs:simpleType>
                    <xs:restriction base="xs:NMTOKEN">
                        <xs:enumeration value="ENG"/>
                        <xs:enumeration value="CES"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
        </xs:extension>
    </xs:simpleContent>
</xs:complexType>

languageType上方,您有简单的内容(xs:string)和必需的lang属性,该属性只能有两个值:ENGCES

如果您想保证恰好有两个元素,则可以在template_data元素定义中使用minOccurs="2"maxOccurs="2"限制given_name子元素:

<xs:element name="template_data">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="given_name" type="languageType" minOccurs="2" maxOccurs="2"/>        
        </xs:sequence>
    </xs:complexType>
    ...

现在,仍有两个given_name元素具有相同的lang="ENG"属性。为了限制我们可以在xs:key元素定义的上下文中添加template_data定义:

<xs:element name="template_data">
    <xs:complexType> ... </xs:complexType>
    <xs:key name="languageKey">
        <xs:selector xpath="given_name" />
        <xs:field xpath="@lang"/>
    </xs:key>
</xs:element>

xs:key使用嵌套的given_name作为选择器,其lang属性作为关键字段。它不允许重复字段,这意味着它不允许两个具有相同given_name个属性的lang个元素。由于您只允许两个,并且它们只能是ENGCES,因此必须为ENG,而另一个CES

现在这些XML文档验证:

<template_data>
    <given_name lang="ENG">Zluty</given_name>
    <given_name lang="CES">Žlutý</given_name>
</template_data>

<template_data>
    <given_name lang="CES">Žlutý</given_name>
    <given_name lang="ENG">Zluty</given_name>
</template_data>

但这些不是:

<template_data>
    <given_name lang="FRA">Zluty</given_name>
    <given_name lang="CES">Žlutý</given_name>
    <given_name lang="ENG">Zluty</given_name>
</template_data>

<template_data>
    <given_name lang="ENG">Zluty</given_name>
    <given_name lang="ENG">Zluty</given_name>
</template_data>

<template_data>
    <given_name lang="ENG">Zluty</given_name>
</template_data>

<template_data>
    <given_name>Zluty</given_name>
    <given_name lang="ENG">Zluty</given_name>
</template_data>