restriction of elements based on another attribute using XSD 1.1

匆匆过客 提交于 2019-12-04 16:15:27

You could use asserts in the Link element (and a enumeration with all the values in the flow attribute).

<xsd:element name="Link">
    <xsd:complexType>
        <xsd:sequence>
            <xsd:element ref="Conn" maxOccurs="unbounded"/>
        </xsd:sequence>
        <xsd:attribute name="service" use="required">
            <xsd:simpleType>
                <xsd:restriction base="xsd:string">
                    <xsd:enumeration value="FILESNF"/>
                    <xsd:enumeration value="MSGSNF"/>
                    <xsd:enumeration value="MSGRT"/>
                    <xsd:enumeration value="FILERT"/>
                </xsd:restriction>
            </xsd:simpleType>
        </xsd:attribute>
        <xsd:assert test="(@service ne 'MSGRT') or (count(Conn[count(BaPath[@flow eq 'TRS']) eq 1 and count(BaPath[@flow eq 'ZTRS']) eq 1 and count(BaPath) eq 2]) eq count(Conn))"></xsd:assert>
        <xsd:assert test="(@service ne 'FILESNF') or (count(Conn[count(BaPath[@flow eq 'FTS']) eq 1 and count(BaPath[@flow eq 'MSSDN']) eq 1 and count(BaPath[@flow eq 'ZFTS']) eq 1 and count(BaPath) eq 3]) eq count(Conn))"></xsd:assert>
    </xsd:complexType>
</xsd:element>

Explanation of one of the assert (the other asserts would be similar):

(@service ne 'MSGRT') or (count(Conn[count(BaPath[@flow eq 'TRS']) eq 1 and count(BaPath[@flow eq 'ZTRS']) eq 1 and count(BaPath) eq 2]) eq count(Conn))

First we check the service attribute. Then, using Conn[count(BaPath[@flow eq 'TRS']) eq 1 and count(BaPath[@flow eq 'ZTRS']) eq 1 and count(BaPath) eq 2] we are selecting all the Conn element of the Link that have exactly two BaPath childs (one with flow=TRS and other with flow=ZTRS). After that we check that all of the Conn elements pass that restriction.

So, using that, this example will be valid:

<Link service="MSGRT">
    <Conn>
        <BaPath flow="TRS"></BaPath>
        <BaPath flow="ZTRS"></BaPath>
    </Conn>    
</Link>

This example will not be valid:

<Link service="MSGRT">
    <Conn>
        <BaPath flow="MSSDN"></BaPath>
        <BaPath flow="ZTRS"></BaPath>
    </Conn>    
</Link>

This example will not be valid:

<Link service="MSGRT">
    <Conn>
        <BaPath flow="TRS"></BaPath>
    </Conn>    
</Link>

This example will not be valid:

<Link service="MSGRT">
    <Conn>
        <BaPath flow="TRS"></BaPath>
        <BaPath flow="ZTRS"></BaPath>
        <BaPath flow="ZFTS"></BaPath>
    </Conn>    
</Link>

Edit:

Another option it's to use conditional type alternatives (example here), but you would probably need to duplicate parts of your Schema.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!