XSD 两个同名但属性值不同的元素 [英] XSD Two elements with the same name but different attribute value

查看:36
本文介绍了XSD 两个同名但属性值不同的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to define an XSD template for the following:

<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 验证器都会对此表示抗议.

Problem is, this defines an element with one and the same name two times, each time with a different type, to which any XSD validator I've found protests.

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

As far as I know, you can require an attribute to have a specific value with the fixed option, and that is included in the definition of a (complex) type. So if you want the attribute with a different value, you would have to define a new type.

我需要的是 template_data 来包含两个 given_namelang="CES" 只包含一次,<代码>lang="ENG".有没有办法为此编写 xsd 验证架构,或者这是不可能的(例如,如果 xml 输入不符合标准)?

What I need is the template_data to include both given_names, exactly once with lang="CES", and exactly once with lang="ENG". Is there a way to write an xsd validation schema for that, or is that impossible (for example if the xml input doesn't conform to standards)?

推荐答案

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

You can't declare two elements with the same name with different types in the same context, but I think I understand what you want to do.

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

If you really had elements with very different contents, it would make sense to create two types (and it would also make sense for them to have different names or to at least occur in another context). Since your data is similar, and the main difference is an attribute which describes the text content of the element, you can create one type and restrict the values the attribute can receive:

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

In languageType above you have simple content (xs:string) and a required lang attribute which can only have two values: ENG or CES.

如果你想保证正好有两个元素,你可以在你的 template_data 元素定义中使用 minOccurs="2"maxOccurs= 来限制它given_name 子元素的2":

If you want to guarantee that there are exactly two elements, you can restrict that in your template_data element definition with minOccurs="2" and maxOccurs="2" for the given_name child element:

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

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

Now it is still possible to have two given_name elements with the same lang="ENG" attribute. To restrict that we can add a xs:key definition in the context of template_data element definition:

<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 属性作为键字段.它不允许重复字段,这意味着它不允许两个具有相同 lang 属性的 given_name 元素.因为你只允许两个,而且它们只能是 ENGCES,一个必须是 ENG,另一个是 CES.

The xs:key uses the nested given_name as a selector and its lang attribute as the key field. It won't allow duplicate fields, that means it will not allow two given_name elements with the same lang atrributes. Since you only allow two, and they can only be ENG or CES, one has to be ENG, and the other CES.

现在验证这些 XML 文档:

Now these XML document validate:

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

这篇关于XSD 两个同名但属性值不同的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆