代码之家  ›  专栏  ›  技术社区  ›  pbajsarowicz

XSD将XML元素值约束到现有的XML属性值?

  •  2
  • pbajsarowicz  · 技术社区  · 8 年前

    目标是限制 BEST_FRIEND_ID 具有现有值 FRIEND_ID 该XML中的属性:

    friends.xml

    <?xml version="1.0"?>
    <FRIENDS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:noNamespaceSchemaLocation="friends.xsd">
        <FRIEND FRIEND_ID="1">
            <NAME>John</NAME>
            <BEST_FRIEND_ID>2</BEST_FRIEND_ID>
        </FRIEND>
        <FRIEND FRIEND_ID="2">
            <NAME>Kate</NAME>
            <BEST_FRIEND_ID>1</BEST_FRIEND_ID>
        </FRIEND>
    </FRIENDS>
    

    E、 g.对于给定的XML,如果我更改了 BEST_FRIEND_ID 元素 3 .

    friends.xsd

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
        xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning">
        <xs:complexType name="FriendsType">
            <xs:sequence>
                <xs:element ref="FRIEND" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
        <xs:complexType name="FriendType">
            <xs:sequence>
                <xs:element ref="NAME"/>
                <xs:element ref="BEST_FRIEND_ID"/>
            </xs:sequence>
            <xs:attribute name="FRIEND_ID" type="xs:integer"/>
        </xs:complexType>
    
        <xs:element name="FRIENDS" type="FriendsType"/>
        <xs:element name="FRIEND" type="FriendType"/>
        <xs:element name="NAME" type="xs:string"/>
        <xs:element name="BEST_FRIEND_ID" type="xs:integer"/>
    </xs:schema>
    

    我的想法是使用断言的力量(XSD 1.1)。这就是我到目前为止发现的

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
        xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1">
        <xs:complexType name="FriendsType">
            <xs:sequence>
                <xs:element ref="FRIEND" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
        <xs:complexType name="FriendType">
            <xs:sequence>
                <xs:element ref="NAME"/>
                <xs:element ref="BEST_FRIEND_ID"/>
            </xs:sequence>
            <xs:attribute name="FRIEND_ID" type="xs:integer"/>
        </xs:complexType>
        <xs:complexType name="IdConstrain">
            <xs:simpleContent>
                <xs:extension base="xs:integer">
                    <xs:assert test="$value = @FRIEND_ID"/>
                </xs:extension>
            </xs:simpleContent>
        </xs:complexType>
    
        <xs:element name="FRIENDS" type="FriendsType"/>
        <xs:element name="FRIEND" type="FriendType"/>
        <xs:element name="NAME" type="xs:string"/>
        <xs:element name="BEST_FRIEND_ID" type="IdConstrain"/>
    </xs:schema>
    

    严重性:错误描述:cvc断言:断言评估 架构类型上元素“BEST_FRIEND_ID”的(“$value=@FRIEND-ID”) “IdConstrain”未成功。开始位置:6:10结束位置: 6: 25网址: http://www.w3.org/TR/xmlschema11-1/#cvc-assertion

    我也尝试过类似的东西 BEST_FRIEND_ID[contains(., @FRIEND_ID)] 但它也不起作用。

    1 回复  |  直到 8 年前
        1
  •  1
  •   Jose Da Silva Gomes Tarsbir Singh    8 年前

    您应该使用以下方法检查每个好友id是否都是现有的好友id。您还应该检查好友id是否不等于自身:

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
        elementFormDefault="qualified"
        xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
        vc:minVersion="1.1">
    
        <xs:complexType name="FriendsType">
            <xs:sequence>
                <xs:element ref="FRIEND" maxOccurs="unbounded"/>
            </xs:sequence>
            <xs:assert test="every $bfid in FRIEND/BEST_FRIEND_ID
                satisfies $bfid = (FRIEND/@FRIEND_ID)"/>
            <!-- Optional check best friend is not equals to itself -->
            <xs:assert test="every $fr in FRIEND
                satisfies $fr/@FRIEND_ID != $fr/BEST_FRIEND_ID"/>
        </xs:complexType>
    
        <xs:complexType name="FriendType">
            <xs:sequence>
                <xs:element ref="NAME"/>
                <xs:element ref="BEST_FRIEND_ID"/>
            </xs:sequence>
            <xs:attribute name="FRIEND_ID" type="xs:integer"/>
        </xs:complexType>
    
        <xs:element name="FRIENDS" type="FriendsType"/>
        <xs:element name="FRIEND" type="FriendType"/>
        <xs:element name="NAME" type="xs:string"/>
        <xs:element name="BEST_FRIEND_ID" type="xs:integer"/>
    </xs:schema>
    

    您还可以检查bestfriend id是否与内部的朋友id不同 FRIEND 标记而不是 FRIENDS 标签

    <xs:complexType name="FriendType">
        <xs:sequence>
            <xs:element ref="NAME"/>
            <xs:element ref="BEST_FRIEND_ID"/>
        </xs:sequence>
        <xs:attribute name="FRIEND_ID" type="xs:integer"/>
        <xs:assert test="@FRIEND_ID != BEST_FRIEND_ID"/>
    </xs:complexType>