仅允许 XSD 中的其他现有 XML 值? (xs:key 和 xs:keyref)
Allow only other existing XML values in XSD? (xs:key and xs:keyref)
我们举下面的例子XML:
<device>
<name>NiceDevice</name>
<value>123</value>
</device>
<user>
<name>user1</name>
<usesDevice>NiceDevice</usesDevice>
</user>
<user>
<name>user2</name>
<usesDevice>NiceDevice</usesDevice>
</user>
由此 XSD 验证:
<xs:element name="device" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<element name="name" type="xs:string"/>
<element name="value" type="xs:integer"/>
</xs:complexType>
</xs:element>
<xs:element name="user" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<element name="name" type="xs:string"/>
<element name="usesDevice" type="xs:string"/>
</xs:complexType>
</xs:element>
我现在想做的是仅验证 user/usesDevice
的值在某处也显示为 device/value
的 xml。
或者换句话说:我只想允许使用在某处定义的设备。
意思是下面的XML应该不是有效的:
<device>
<name>NiceDevice</name>
<value>123</value>
</device>
<user>
<name>user1</name>
<usesDevice>NiceDevice</usesDevice>
</user>
<user>
<name>user2</name>
<usesDevice>BadDevice</usesDevice>
</user>
因为 BadDevice
从未用作 device/name
。
使用 xs:key
和 xs:keyref
约束 usesDevices
的值为 device
name
:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="r">
<xs:complexType>
<xs:sequence>
<xs:element name="device" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="value" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="user" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="usesDevice" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:key name="deviceKey" >
<xs:selector xpath="device"/>
<xs:field xpath="name" />
</xs:key>
<xs:keyref name="deviceKeyRef" refer="deviceKey">
<xs:selector xpath="user" />
<xs:field xpath="usesDevice" />
</xs:keyref>
</xs:element>
</xs:schema>
那么这个XML就有效了:
<?xml version="1.0" encoding="UTF-8"?>
<r xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="try.xsd">
<device>
<name>NiceDevice</name>
<value>123</value>
</device>
<user>
<name>user1</name>
<usesDevice>NiceDevice</usesDevice>
</user>
<user>
<name>user2</name>
<usesDevice>NiceDevice</usesDevice>
</user>
</r>
但是这个XML,
<?xml version="1.0" encoding="UTF-8"?>
<r xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="try.xsd">
<device>
<name>NiceDevice</name>
<value>123</value>
</device>
<user>
<name>user1</name>
<usesDevice>NiceDevice</usesDevice>
</user>
<user>
<name>user2</name>
<usesDevice>BadDevice</usesDevice>
</user>
</r>
不会,
[Error] try.xml:16:5: cvc-identity-constraint.4.3: Key 'deviceKeyRef' with value 'BadDevice' not found for identity constraint of element 'r'.
根据要求。
请注意,我已向您的 XML 添加了一个根元素,这是使您的 XML 格式正确所必需的。
我们举下面的例子XML:
<device>
<name>NiceDevice</name>
<value>123</value>
</device>
<user>
<name>user1</name>
<usesDevice>NiceDevice</usesDevice>
</user>
<user>
<name>user2</name>
<usesDevice>NiceDevice</usesDevice>
</user>
由此 XSD 验证:
<xs:element name="device" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<element name="name" type="xs:string"/>
<element name="value" type="xs:integer"/>
</xs:complexType>
</xs:element>
<xs:element name="user" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<element name="name" type="xs:string"/>
<element name="usesDevice" type="xs:string"/>
</xs:complexType>
</xs:element>
我现在想做的是仅验证 user/usesDevice
的值在某处也显示为 device/value
的 xml。
或者换句话说:我只想允许使用在某处定义的设备。
意思是下面的XML应该不是有效的:
<device>
<name>NiceDevice</name>
<value>123</value>
</device>
<user>
<name>user1</name>
<usesDevice>NiceDevice</usesDevice>
</user>
<user>
<name>user2</name>
<usesDevice>BadDevice</usesDevice>
</user>
因为 BadDevice
从未用作 device/name
。
使用 xs:key
和 xs:keyref
约束 usesDevices
的值为 device
name
:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="r">
<xs:complexType>
<xs:sequence>
<xs:element name="device" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="value" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="user" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="usesDevice" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:key name="deviceKey" >
<xs:selector xpath="device"/>
<xs:field xpath="name" />
</xs:key>
<xs:keyref name="deviceKeyRef" refer="deviceKey">
<xs:selector xpath="user" />
<xs:field xpath="usesDevice" />
</xs:keyref>
</xs:element>
</xs:schema>
那么这个XML就有效了:
<?xml version="1.0" encoding="UTF-8"?>
<r xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="try.xsd">
<device>
<name>NiceDevice</name>
<value>123</value>
</device>
<user>
<name>user1</name>
<usesDevice>NiceDevice</usesDevice>
</user>
<user>
<name>user2</name>
<usesDevice>NiceDevice</usesDevice>
</user>
</r>
但是这个XML,
<?xml version="1.0" encoding="UTF-8"?>
<r xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="try.xsd">
<device>
<name>NiceDevice</name>
<value>123</value>
</device>
<user>
<name>user1</name>
<usesDevice>NiceDevice</usesDevice>
</user>
<user>
<name>user2</name>
<usesDevice>BadDevice</usesDevice>
</user>
</r>
不会,
[Error] try.xml:16:5: cvc-identity-constraint.4.3: Key 'deviceKeyRef' with value 'BadDevice' not found for identity constraint of element 'r'.
根据要求。
请注意,我已向您的 XML 添加了一个根元素,这是使您的 XML 格式正确所必需的。