XML 基于使用的架构元素限制

XML Schema element restrictions based on usage

我定义了一个名为 transform

的元素
<xs:element name="transformName" type="xs:string"/>

我想在其他各种元素中使用该元素。例如

<xs:element name="input">
    <xs:complexType>
        <xs:sequence>
            <xs:element ref="transformName"/>
            <xs:element name="description" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

<xs:element name="output">
    <xs:complexType>
        <xs:sequence>
            <xs:element ref="transformName"/>
            <xs:element name="description" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

我知道我可以使用

之类的东西来限制可以放入转换名称的内容
<xs:element name="transformName">
    <xs:simpleType>
        <xs:restriction base="xs:string">
            <xs:pattern value="transform\.\S+\.\S+\.\d{1}\.v\d+"/>
        </xs:restriction>
    </xs:simpleType>
</xs:element>

但是有什么方法可以改变每个父元素的限制吗?

例如,在输入中使用时可能是:

<xs:restriction base="xs:string">
    <xs:pattern value="inputTransform\.\S+\.\d{1}"/>
</xs:restriction>

但在输出中使用时可能是:

<xs:restriction base="xs:string">
    <xs:pattern value="outputTransform\.\S+\.\d{1}"/>
</xs:restriction>

因为你说限制在XSD-1.0,所以我避免使用xs:alternative。通过

"Define a type for each possibility/parent element."

我的意思是为每个 xs:pattern 创建一个 type
因此,对于这样的示例 XML:

<root>
    <input>
        <transformName>inputTransform.A.1</transformName>
        <description />
    </input>
    <output>
        <transformName>outputTransform.C.2</transformName>
        <description />
    </output>
</root>

...验证它的 XSD-1.0 代码可能如下所示:

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

    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="input">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="transformName" type="tnInput" />
                            <xs:element name="description" type="xs:string" />
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element name="output">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="transformName" type="tnOutput" />
                            <xs:element name="description" type="xs:string" />
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:simpleType name="tnInput">
        <xs:restriction base="xs:string">
            <xs:pattern value="inputTransform\.\S+\.\d{1}"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="tnOutput">
        <xs:restriction base="xs:string">
            <xs:pattern value="outputTransform\.\S+\.\d{1}"/>
        </xs:restriction>
    </xs:simpleType>

</xs:schema>

看到它为每个父元素 (input/output) 定义了不同的 simpleType 和不同的 xs:pattern


为了避免这种情况,您必须使用 XSD-1.1 xs:alternative 方法,它看起来像这样:

<xs:element name="transformName" type="xs:string">
    <xs:alternative test="ancestor::input"  type="inputType"/>
    <xs:alternative test="ancestor::output" type="outputType"/>
</xs:element>

我无法完成这项工作,但如果您想保留一个元素作为参考,这是可行的方法。