如何根据其他元素中的属性值限制XML属性的值?

时间:2014-01-03 12:50:21

标签: xml xpath xsd

我有这样的XML元素:

<characteristic name="Length"... />
<characteristic name="Width"... />
<!-- etc. -->

是否可以将另一个属性的值限制为(XPath)“// characteristic / @ name”的值之一?

所以这是允许的:

<widget>
    <characteristic name="Length">100</characteristic>
</widget>

但不允许这样做:

<widget>
    <characteristic name="Bananas">33</characteristic>
</widget>

(因为“香蕉”不是名字特征之一。)

我认为这可以使用“key”和“keyref”来完成,但是当key和ref都是属性值时,我不确定如何实现它。

另外,如果特征在不同的XML文档中列出到窗口小部件,我该如何做? (这有可能吗?)理想情况下我想使用XSD 1.0,但我有兴趣知道XSD 1.1是否在这里增加了一些有用的东西。

2 个答案:

答案 0 :(得分:2)

以下是示例模式:

<xs:schema
  xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="characteristics">
          <xs:complexType>
            <xs:sequence maxOccurs="unbounded">
              <xs:element name="characteristic">
                <xs:complexType>
                  <xs:attribute name="name" type="xs:string"/>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="widgets">
          <xs:complexType>
            <xs:sequence maxOccurs="unbounded">
              <xs:element name="widget">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="characteristic">
                      <xs:complexType>
                        <xs:simpleContent>
                          <xs:extension base="xs:integer">
                            <xs:attribute name="name" type="xs:string"/>
                          </xs:extension>
                        </xs:simpleContent>
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
    <xs:key name="cname">
      <xs:selector xpath="characteristics/characteristic"/>
      <xs:field xpath="@name"/>
    </xs:key>
    <xs:keyref name="cname-ref" refer="cname">
      <xs:selector xpath="widgets/widget/characteristic"/>
      <xs:field xpath="@name"/>
    </xs:keyref>
  </xs:element>

</xs:schema>

应用于实例时

<root>
  <characteristics>
    <characteristic name="Length"/>
    <characteristic name="Width"/>
  </characteristics>
  <widgets>
    <widget>
        <characteristic name="Length">100</characteristic>
    </widget>

    <widget>
        <characteristic name="Bananas">33</characteristic>
    </widget>
  </widgets>
</root>

Xerces报告您想要的错误:“test2014010301.xml:15:cvc-identity-constraint.4.3:键'cname-ref',其元素'root'的标识限制未找到值'Bananas'。”

答案 1 :(得分:1)

在XSD 1.0中,您可能无法做到这一点(但我不确定,因为我不确定“受控”特征是如何与“控制”特征相关的:它可能与key / keyref有关正如你的建议)。

在XSD 1.1中,可以使用断言或条件类型赋值来完成。

XSD 1.1目前在Saxon,Xerces和Altova中实施。