【问题标题】:XSD key/keyref beginner questionXSD key/keyref 初学者问题
【发布时间】:2011-01-02 04:06:49
【问题描述】:

我正在尝试实现一个非常简单的 XML 模式约束。

idref 元素的属性 类型 应该只是 允许有一个匹配的值 至少一个上的 id 属性 元素 .

如果这对您没有任何意义,那么请看下面的示例 XML 文档,我认为它实际上比我试图用文字来解释它更好。

那么,问题:为什么 xmllint 让下面的 schema/xml 组合通过(它说文档是有效的)? 如何修复它以实现所需的约束?

架构:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="test" xmlns="test" elementFormDefault="qualified">

    <xs:element name="foo">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="bar" minOccurs="0" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:attribute name="id" use="required" type="xs:string" />
                    </xs:complexType>
                </xs:element>
                <xs:element name="batz" minOccurs="0" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:attribute name="idref" use="required" type="xs:string" />
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>

        <xs:key name="ID">
            <xs:selector xpath="./bar" />
            <xs:field xpath="@id" />
        </xs:key>

        <xs:keyref name="IDREF" refer="ID">
            <xs:selector xpath="./batz" />
            <xs:field xpath="@idref" />
        </xs:keyref>

    </xs:element>
</xs:schema>

文件:

<?xml version="1.0"?>
<foo xmlns="test">
    <bar id="1" />
    <bar id="2" />
    <batz idref="1" /> <!-- this should succeed because <bar id="1"> exists -->
    <batz idref="3" /> <!-- this should FAIL -->
</foo>

【问题讨论】:

    标签: xml xsd schema keyref


    【解决方案1】:

    即使分配了模式位置,这也不适用于所有解析器。

    <?xml version="1.0"?>
    <foo xmlns="test"   
         xsi:schemaLocation="test test.xsd"  
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <bar id="1" />
        <bar id="2" />
        <batz idref="1" /> <!-- this should succeed because <bar id="1"> exists -->
        <batz idref="3" /> <!-- this should FAIL -->
    </foo>
    

    这也会验证,因为键没有引用目标命名空间。

    需要在 XSD 中进行的更改是

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
        targetNamespace="test" 
        xmlns:t="test"
        xmlns="test" elementFormDefault="qualified">
    

    <xs:key name="ID">
        <xs:selector xpath="./t:bar" />
        <xs:field xpath="@id" />
    </xs:key>
    
    <xs:keyref name="IDREF" refer="ID">
        <xs:selector xpath="./t:batz" />
        <xs:field xpath="@idref" />
    </xs:keyref>
    

    有关此行为的讨论,请参阅#1545101

    【讨论】:

      【解决方案2】:

      如图所示,您的 XML 文档不包含 schemaLocation。当 XML 文档不引用模式或 DTD 时,它可以通过格式正确的 XML 简单地通过验证。 (这曾经发生在一位同事身上,使用了不同的验证器。我认为这是一个错误,验证器至少没有给出缺少架构或 DTD 的警告。但我离题了。)

      无论如何,应该是这样的:

      <?xml version="1.0"?>
      <foo
        xmlns="test" <!-- This is bad form, by the way... -->
        xsi:schemaLocation="test /path/to/schema/document"
          <bar id="1" />
          <bar id="2" />
          <batz idref="1" /> <!-- this should succeed because <bar id="1"> exists -->
          <batz idref="3" /> <!-- this should FAIL -->
      </foo>
      

      【讨论】:

      • 谢谢!这就是问题所在。
      • 使用它仍然在某些验证器中进行验证。但当然你需要引用架构。
      猜你喜欢
      • 1970-01-01
      • 2010-10-27
      • 1970-01-01
      • 2013-04-06
      • 2020-01-04
      • 2020-11-23
      • 2015-03-16
      • 2012-04-15
      • 1970-01-01
      相关资源
      最近更新 更多