基于父元素的属性

Attributes based on parent element

我有一个树结构,我想为其创建模式。每个节点下都有两个节点列表。这些列表可以是相同类型的元素。但是,一个列表中的元素需要两个额外的属性有没有办法根据元素的父元素来要求元素的属性。

我尝试创建单独的列表类型。一种列表类型只包含元素的选择。另一个包含相同的选择类型,但每个类型都被扩展为需要额外的参数。这行得通而且非常简单,但它似乎不必要地冗长,我想知道是否有更聪明的解决方案。当前架构如下所示:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://www.example.org/ElementSchema" xmlns="http://www.example.org/ElementSchema"
    elementFormDefault="qualified">

    <!--BaseElementTypes -->
    <xs:element name="BaseElement" type="BaseElementType" />
    <xs:element name="DoubleElement" type="DoubleElementType" />
    <xs:element name="BoundedDoubleElement" type="BoundedDoubleElementType" />

    <!--ElementListTypes -->
    <xs:complexType name="ChildListType">
        <xs:choice minOccurs="1" maxOccurs="unbounded">
            <xs:element ref="BaseElement" />
            <xs:element ref="DoubleElement" />
            <xs:element ref="BoundedDoubleElement" />
        </xs:choice>
    </xs:complexType>

    <xs:complexType name="PropertyListType">
        <xs:choice minOccurs="1" maxOccurs="unbounded">
            <xs:element name="BaseElement">
                <xs:complexType>
                    <xs:complexContent>
                        <xs:extension base="BaseElementType">
                            <xs:attribute name="Role" type="xs:string" use="required" />
                            <xs:attribute name="Tag" type="xs:integer" use="required" />
                        </xs:extension>
                    </xs:complexContent>
                </xs:complexType>
            </xs:element>
            <xs:element name="DoubleElement">
                <xs:complexType>
                    <xs:complexContent>
                        <xs:extension base="DoubleElementType">
                            <xs:attribute name="Role" type="xs:string" use="required" />
                            <xs:attribute name="Tag" type="xs:integer" use="required" />
                        </xs:extension>
                    </xs:complexContent>
                </xs:complexType>
            </xs:element>
            <xs:element name="BoundedDoubleElement">
                <xs:complexType>
                    <xs:complexContent>
                        <xs:extension base="BoundedDoubleElementType">
                            <xs:attribute name="Role" type="xs:string" use="required" />
                            <xs:attribute name="Tag" type="xs:integer" use="required" />
                        </xs:extension>
                    </xs:complexContent>
                </xs:complexType>
            </xs:element>
        </xs:choice>
    </xs:complexType>


    <!--elementTypes -->
    <xs:complexType name="BaseElementType">
        <xs:sequence>
            <xs:element name="Children" type="ChildListType" minOccurs="0" />
            <xs:element name="Properties" type="PropertyListType"
                minOccurs="0" />
        </xs:sequence>
        <xs:attribute name="ID" type="xs:positiveInteger" use="required" />
        <xs:attribute name="Key" type="xs:string" use="required" />
    </xs:complexType>

    <xs:complexType name="DoubleElementType">
        <xs:complexContent>
            <xs:extension base="BaseElementType">
                <xs:sequence>
                    <xs:element name="Value" type="xs:float" />
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="BoundedDoubleElementType">
        <xs:complexContent>
            <xs:extension base="DoubleElementType">
                <xs:sequence>
                    <xs:element name="DesiredValue" type="xs:float" />
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
</xs:schema>

具体我想知道是否有更好的方法可以达到与PropertyListType相同的结果?

Is there any way to require attributes on an element based on its parent.

XSD1.0,没有.

XSD 1.1 中,是的:将属性设为可选,然后 xs:assert 特定父元素的每个子元素都具有额外的属性。 是一个示例,展示了如何在 XSD 1.1.

中使用 every..satisfies 断言