如何将xsd keyref限制在特定元素?

时间:2014-08-27 23:02:27

标签: xml xsd

W3C在线验证器表示以下XML基于架构有效。但我认为构造模式的方式(特别是使用key / keyref约束)它将是无效的。

架构:     

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://testSchema"
           xmlns="http://testSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">

  <xs:complexType name="defFooType">
    <xs:attribute name="name" type="xs:ID" use="required"/>
  </xs:complexType>

  <xs:complexType name="defBarType">
    <xs:attribute name="name" type="xs:ID" use="required"/>
  </xs:complexType>

  <xs:complexType name="useFooType">
    <xs:attribute name="use" type="xs:IDREF" use="required"/>
  </xs:complexType>

  <xs:complexType name="testType">
    <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:element name="defFoo" type="defFooType"/>
      <xs:element name="defBar" type="defBarType"/>
      <xs:element name="useFoo" type="useFooType"/>
    </xs:choice>
  </xs:complexType>

  <xs:element name="test" type="testType">
    <xs:key name="FOOKEY">
      <xs:selector xpath="./defFoo"/>
      <xs:field xpath="@name"/>
    </xs:key>
    <xs:keyref name="FOOKEYREF" refer="FOOKEY">
      <xs:selector xpath="./useFoo"/>
      <xs:field xpath="@use"/>
    </xs:keyref>
  </xs:element>

</xs:schema>

测试XML:

<?xml version="1.0"?>
<test xmlns="http://testSchema">
  <defFoo name="foo1"/>
  <defBar name="bar1"/>
  <useFoo use="bar1"/>
</test>

我正在尝试限制<useFoo>元素'use属性,以仅引用name元素的<defFoo>属性。我不明白为什么<useFoo use="bar1"/>不会导致验证失败。我是否设置了密钥/密钥错误?我还需要添加其他东西吗?

1 个答案:

答案 0 :(得分:3)

我找到了答案,所以不要删除我认为我会发布的问题,以防其他人遇到这个问题。

似乎正在定义的模式需要xs:selector语句中XPATH的目标命名空间才能找到我想要它找到的内容。显然,当元素在默认命名空间中时,XPATH表达式将不会执行我期望的操作。

以下是给我线索的参考资料:

  

“在定义时必须特别考虑名称空间   身份约束。合格的元素类型名称和属性名称   在XPath表达式中使用必须以前缀为前缀   合法.....请注意,目标命名空间映射到前缀,而不是   而不是默认的命名空间。这是因为XPath表达式   不受默认命名空间声明的影响。不合格的名字   在XPath表达式中总是假定为   没有命名空间。“

     

Walmsley,Priscilla(2001-12-07)。最终的XML模式(Charles F.   Goldfarb最终XML系列)(Kindle地点6982-6984)。皮尔逊   教育。

虽然这可能不是在谈论我正在处理的确切问题,但我能够通过为我的架构使用非默认命名空间来解决我的问题。

因此,这个结果模式会得到我期望的验证错误:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://testSchema"
           xmlns:mine="http://testSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">

  <xs:complexType name="defFooType">
    <xs:attribute name="name" type="xs:ID" use="required"/>
  </xs:complexType>

  <xs:complexType name="defBarType">
    <xs:attribute name="name" type="xs:ID" use="required"/>
  </xs:complexType>

  <xs:complexType name="useFooType">
    <xs:attribute name="use" type="xs:IDREF" use="required"/>
  </xs:complexType>

  <xs:complexType name="testType">
    <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:element name="defFoo" type="mine:defFooType"/>
      <xs:element name="defBar" type="mine:defBarType"/>
      <xs:element name="useFoo" type="mine:useFooType"/>
    </xs:choice>
  </xs:complexType>

  <xs:element name="test" type="mine:testType">
    <xs:key name="FOOKEY">
      <xs:selector xpath="./mine:defFoo"/>
      <xs:field xpath="@name"/>
    </xs:key>
    <xs:keyref name="FOOKEYREF" refer="mine:FOOKEY">
      <xs:selector xpath="./mine:useFoo"/>
      <xs:field xpath="@use"/>
    </xs:keyref>
  </xs:element>

</xs:schema>