XSD 将 XML 元素值限制为现有 XML 属性值?
XSD to constrain XML element values to existing XML attribute values?
目标是限制 BEST_FRIEND_ID
在此 XML:
中具有现有 FRIEND_ID
属性的值
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>
例如对于给定的 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>
验证失败:
Severity: error Description: cvc-assertion: Assertion evaluation
('$value = @FRIEND_ID') for element 'BEST_FRIEND_ID' on schema type
'IdConstrain' did not succeed. Start location: 6:10 End location:
6:25 URL: http://www.w3.org/TR/xmlschema11-1/#cvc-assertion
我也尝试过 BEST_FRIEND_ID[contains(., @FRIEND_ID)]
但效果不佳。
您应该使用以下方法检查每个最好的朋友 ID 是否都是现有的朋友 ID。您还应该检查 bestfriend 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 是否与 FRIEND
标签而不是 FRIENDS
标签内的朋友 id 不同。
<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>
目标是限制 BEST_FRIEND_ID
在此 XML:
FRIEND_ID
属性的值
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>
例如对于给定的 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>
验证失败:
Severity: error Description: cvc-assertion: Assertion evaluation ('$value = @FRIEND_ID') for element 'BEST_FRIEND_ID' on schema type 'IdConstrain' did not succeed. Start location: 6:10 End location: 6:25 URL: http://www.w3.org/TR/xmlschema11-1/#cvc-assertion
我也尝试过 BEST_FRIEND_ID[contains(., @FRIEND_ID)]
但效果不佳。
您应该使用以下方法检查每个最好的朋友 ID 是否都是现有的朋友 ID。您还应该检查 bestfriend 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 是否与 FRIEND
标签而不是 FRIENDS
标签内的朋友 id 不同。
<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>