简体   繁体   English

XML Schema中的属性/元素共现约束

[英]Attribute/element co-occurrence constraint in XML Schema

Is it possible to create an XML Schema which imposes a co-occurrence constraint to an attribute/element pair? 是否可以创建一个XML Schema,它对属性/元素对强加共生约束?

<primitive-list>
    <primitive name="P1">
        <definition><!-- primitive specification --></definition>
    </primitive>
    <primitive name="P2">
        <definition><!-- primitive specification --></definition>
    </primitive>

    <!-- other common primitives are specified here-->

<primitive-list>

<composite-list>
    <composite name="C1">
        <primitive ref="P1" />
        <primitive ref="P2" />
        <primitive>
            <definition><!-- inline primitive specification --></definition>
        </primitive>        
    </composite>

    <!-- Other compisites are specified here-->

</composite-list>

The schema should imply that: 架构应该意味着:

  • If a primitive element is specified inside a primitive-list element, then it should contain the name attribute and the embedded definition element, but not the ref attribute. 如果原始的列表元素中指定了原始的元素,那么它应该包含name属性和嵌入式定义元素,但不是ref属性。
  • If a primitive element is specified in the composite element, then it should contain either the ref attribute or the definition element. 如果在复合元素中指定了原始元素,那么它应该包含ref属性或definition元素。 The name is allowed in neither cases. 两种情况都不允许使用该名称

I am pretty sure that it is possible since the element element in XML Schema itself behaves just like that. 我很确定它是可能的,因为XML Schema中的元素元素本身就像那样。 So anybody who is in possession of that sacred knowledge please share :-) 所以任何拥有这种神圣知识的人请分享:-)

Thank you in advance. 先感谢您。

After searching on the Internet and digging in some books I figured out how to implement that. 在互联网上搜索并挖掘了一些书后,我想出了如何实现它。

First of all we need to define a generic type which accommodates all attributes and elements from both kinds of the primitive element. 首先,我们需要定义一个泛型类型,它适应两种原始元素的所有属性和元素。 It is assumed that the definition element is defined somewhere else. 假设定义元素在其他地方定义。

<xs:complexType name="primitive" abstract="true">
    <xs:sequence>
        <xs:element ref="definition" minOccurs="0" maxOccurs="unbounded" />
    </xs:sequence>
    <xs:attribute name="name" type="xs:Name" />
    <xs:attribute name="ref" type="xs:Name" />
</xs:complexType>

Then we define two primitive subtypes to be used in the primitive-list and composite respectively. 然后我们定义两个原始子类型分别用于原始列表复合

<xs:complexType name="public-primitive">
    <xs:complexContent>
        <xs:restriction base="primitive">
            <xs:sequence>
                <xs:element ref="definition" minOccurs="1" maxOccurs="unbounded" />
            </xs:sequence>
            <xs:attribute name="name" type="xs:Name" use="required" />
            <xs:attribute name="ref" use="prohibited" />
        </xs:restriction>
    </xs:complexContent>
</xs:complexType>

<xs:complexType name="private-primitive">
    <xs:complexContent>
        <xs:restriction base="primitive">
            <xs:sequence>
                <xs:element ref="definition" minOccurs="0" maxOccurs="unbounded" />
            </xs:sequence>
            <xs:attribute name="name" use="prohibited" />
        </xs:restriction>
    </xs:complexContent>
</xs:complexType>

Now we can define the primitive-list and composite elements in terms of these complex types as follows: 现在我们可以根据这些复杂类型定义基本列表复合元素,如下所示:

<xs:element name="primitive-list">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="primitive" type="public-primitive" maxOccurs="unbounded" />
        </xs:sequence>
    </xs:complexType>
</xs:element>

<xs:element name="composite">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="primitive" type="private-primitive" maxOccurs="unbounded">
                <xs:key name="definition-ref--co-occurrence--constraint">
                    <xs:selector xpath="." />
                    <xs:field xpath="definition|@ref" />
                </xs:key>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:element>

Let's take a look at the original schema requirements and see how they are enforced: 我们来看看原始架构要求,看看它们是如何实施的:

  • If a primitive element is specified inside a primitive-list element, then it should contain the name attribute and the embedded definition element, but not the ref attribute. 如果原始的列表元素中指定了原始的元素,那么它应该包含name属性和嵌入式定义元素,但不是ref属性。

This requirement is enforced by the definition of the public-primitive type alone. 仅通过public-primitive类型的定义来强制执行此要求。

  • If a primitive element is specified in the composite element, then it should contain either the ref attribute or the definition element. 如果在复合元素中指定了原始元素,那么它应该包含ref属性或definition元素。 The name is allowed in neither cases. 两种情况都不允许使用该名称

This requirement is enforced by the definition of the private-primitive type and by the xs:key element specified in the primitive element defined inside of the composite element. 此要求由private-primitive类型的定义和在复合元素内定义的元元素中指定的xs:key元素强制执行。 The xs:key guaranties that either ref or definition is present but not both. xs:密钥保证refdefinition存在但不同时存在。

Yes, this is possible. 是的,这是可能的。 When creating your XML Schema, you will be creating a complex type for each scenario, based on where in the XML tree the element is defined. 在创建XML模式时,您将根据XML树中定义元素的位置为每个方案创建复杂类型。

If I get a moment later on i can try to actually get an example out here for you, I just don't have the time to get it all formatted perfectly for posting here. 如果我过了一会儿,我可以尝试在这里为你做一个例子,我只是没有时间把这一切都完美地发布在这里。

I personally highly recommend looking at this w3schools tutorial , as it should get you what you need. 我个人强烈建议您查看这个w3schools教程 ,因为它应该能满足您的需求。

Ok, here is a sample, this gets you close, the only thing not handled is the primitive and ref attribute on the composite. 好的,这是一个示例,这会让你关闭,唯一没有处理的是复合上的primitive和ref属性。 Looking at what I can find, it does almost seem to be impossible to do this via a schema. 看看我能找到什么,通过模式几乎不可能做到这一点。 I'm not 100% sure though, but in all cases where I have seen this done, a schema like this is used for high level validation and process code is then used to validate the individual items. 我不是100%肯定,但在我看到这一点的所有情况下,这样的模式用于高级验证,然后使用流程代码验证各个项目。

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://www.iowacomputergurus.com/stackoverflow/samples/xsdexample"
    elementFormDefault="qualified"
    xmlns="http://www.iowacomputergurus.com/stackoverflow/samples/xsdexample"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
>

  <xs:complexType name="PrimitiveType">
    <xs:sequence>
      <xs:element name="definition" type="xs:string" minOccurs="1" maxOccurs="1" />
    </xs:sequence>
    <xs:attribute name ="name" use="required" type="xs:string" />
  </xs:complexType>

  <xs:element name="root">
    <xs:complexType>
      <xs:sequence>
          <xs:element name="primitive-list" minOccurs="1" maxOccurs="1">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="primitive" type="PrimitiveType" minOccurs="1" maxOccurs="unbounded" />
              </xs:sequence>
            </xs:complexType>
          </xs:element>
          <xs:element name="composite-list" minOccurs="1" maxOccurs="1">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="composite">
                  <xs:complexType>
                    <xs:sequence>
                      <xs:element name="primitive" minOccurs="1" maxOccurs="unbounded">
                        <xs:complexType>
                          <xs:sequence>
                            <xs:element name="definition" minOccurs="0" maxOccurs="1" />
                          </xs:sequence>
                          <xs:attribute name="ref" use="optional" type="xs:string" />
                        </xs:complexType>
                      </xs:element>
                    </xs:sequence>
                    <xs:attribute name="name" type="xs:string" use="required" />
                  </xs:complexType>
                </xs:element>
              </xs:sequence>
            </xs:complexType>
          </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>  
</xs:schema>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM