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

仅允许XSD中的其他现有XML值吗?(xs:key和xs:keyref)

  •  1
  • Detonar  · 技术社区  · 6 年前

    让我们以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>
    

    我现在要做的是只验证xmls,其中 user/usesDevice 也出现在某处 device/value . 或者换句话说:我只允许使用在某处定义的设备。

    这意味着下面的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 .

    1 回复  |  直到 6 年前
        1
  •  1
  •   kjhughes    6 年前

    使用 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>
    

    不会的,

    [错误]try.xml:16:5:cvc identity constraint.4.3:找不到元素“r”的identity constraint的值为“BadDevice”的键“deviceKeyRef”。

    按要求。

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