2014-08-27 80 views
1

W3C在线验证程序认为下面的XML基于模式有效。但是我认为模式的构造方式(特别是使用key/keyref约束)它是无效的。如何将xsd 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属性只指<defFoo>元素name属性。我不明白为什么<useFoo use="bar1"/>不会导致验证失败。我设置了key/keyref是否错误?还有什么我需要添加?

回答

3

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

似乎所定义的模式需要在xs:selector语句中寻找XPATH的目标命名空间来查找我希望它找到的内容。很显然,当元素处于默认名称空间时,XPATH表达式不会执行我期望的操作。

这是给我的线索参考:

“特别考虑,必须在定义 身份限制时给予命名空间中的XPath表达式中使用的必须是合格的元素类型名和属性名 前缀为 legal .....请注意,目标名称空间映射到前缀,而不是默认名称空间,因为XPath表达式 不受默认名称空间声明的影响。表达式总是假定为 in no namespace。“

Walmsley,Priscilla(2001-12-07)。通用XML模式(Charles F. Goldfarb通用XML系列)(Kindle Locations 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>