我正在尝试为以下内容定义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输入不符合标准)?
答案 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
属性,该属性只能有两个值:ENG
或CES
。
如果您想保证恰好有两个元素,则可以在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
个元素。由于您只允许两个,并且它们只能是ENG
或CES
,因此必须为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>