本文介绍了只允许 XSD 中的其他现有 XML 值?(xs:key 和 xs:keyref)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们以下面的 XML 为例:

Let's take the following example 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 验证:

validated by this 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.或者换句话说:我只想允许使用在某处定义的设备.

What I now want to do is validate only xmls where the value of user/usesDevice also appears somewhere as device/value.Or in other words: I want to only allow the use of devices which were defined somewhere.

意味着以下 XML 应该有效:

Meaning the following XML should not be valid:

<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:keyxs:keyref 来约束 usesDevices有一个 device name 的值:

Use xs:key and xs:keyref to constrain usesDevices to have a value of a 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 将是有效的:

Then this XML will be valid:

<?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>

不会,

[错误] try.xml:16:5: cvc-identity-constraint.4.3: 没有为元素r"的标识约束找到值为BadDevice"的键deviceKeyRef".

根据要求.

请注意,我已向您的 XML 添加了一个根元素,这是您的 XML 格式良好所必需的.

Note that I've added to your XML a single root element, which is required for your XML to be well-formed.

这篇关于只允许 XSD 中的其他现有 XML 值?(xs:key 和 xs:keyref)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 10:10