【问题标题】:XSD - keyref in complexeType - No match foundXSD - complexeType 中的 keyref - 未找到匹配项
【发布时间】:2021-09-11 15:04:21
【问题描述】:

我编写了一个 XSD 来定义以下元素:

  • 词汇表
    • 定义[术语=唯一]
      • 术语 [ref=术语]

“词汇表”包含“定义”列表。每个“定义”都有一个唯一的属性“术语”。 “定义”可以包含带有“术语”元素的混合文本。每个“术语”都有一个属性“ref”,它引用定义的术语属性。

请注意keyref(命名为“termRef”)是complexType定义(命名为“textType”)的一部分,因为这种类型应该在xsd文档的几个地方都有用,而不仅仅是在“定义”。

我不明白为什么 XML linter 找不到关键引用。

这是我写的代码:

XSD:

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

    <xs:complexType name="textType" mixed="true">
        <xs:choice maxOccurs="unbounded">
            <xs:element name="term" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:simpleContent>
                        <xs:extension base="xs:normalizedString">
                            <xs:attribute name="ref" use="required" type="xs:token"/>
                        </xs:extension>
                    </xs:simpleContent>
                </xs:complexType>
                <xs:keyref name="termRef" refer="glossaryTermUnique">
                    <xs:selector xpath="."/>
                    <xs:field xpath="@ref"/>
                </xs:keyref>
            </xs:element>
        </xs:choice>
    </xs:complexType>

    <xs:element name="foo">
        <xs:complexType>
            <xs:sequence>

                <xs:element name="glossary">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="definition" minOccurs="0" maxOccurs="unbounded">
                                <xs:complexType>
                                    <xs:complexContent>
                                        <xs:extension base="textType">
                                            <xs:attribute name="term" use="required" type="xs:token"/>
                                        </xs:extension>
                                    </xs:complexContent>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                    <xs:unique name="glossaryTermUnique">
                        <xs:selector xpath="xsfoo:definition"/>
                        <xs:field xpath="@term"/>
                    </xs:unique>
                </xs:element>

            </xs:sequence>
        </xs:complexType>
    </xs:element>

</xs:schema>

XML:


<?xml version="1.0"?>
<foo
        xmlns="foo"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="foo/none.xsd">
    <glossary>
        <definition term="ik 1">identification key 1</definition>
        <definition term="ik 2">identification key 2 with <term ref="ik 1">a ik 1 reference</term></definition>
    </glossary>
</foo>

这是来自 xmllint 的错误消息:

架构有效性错误:元素“{foo}term”:未找到 keyref '{foo}termRef' 的键序列 ['ik 1'] 的匹配项。

非常感谢您的帮助! :)

【问题讨论】:

    标签: xml xsd keyref


    【解决方案1】:

    Xerces 说,我认为 XSD 中元素的嵌套很重要

    身份约束错误:keyref 身份约束“termRef” 指的是超出范围的键或唯一键。

    同时

                   <xs:unique name="glossaryTermUnique">
                        <xs:selector xpath="xsfoo:definition"/>
                        <xs:field xpath="@term"/>
                    </xs:unique>
                    <xs:keyref name="termRef" refer="glossaryTermUnique">
                        <xs:selector xpath="xsfoo:definition/xsfoo:term"/>
                        <xs:field xpath="@ref"/>
                    </xs:keyref>
    

    修复了它的样子。

    【讨论】:

    • 实际上,当我在unique 定义之后移动keyref 时,xml 被验证。但是,这意味着 keyref 不再属于 textType 定义。它应该是它的一部分,否则我们每次在 xsd 中使用 textType 时都必须复制 keyref 定义。 (而且,我想知道对于不是唯一旁边的其他用法是否不会出现相同的错误。)
    【解决方案2】:

    正如之前的答案所指出的,嵌套似乎是关键。

    为了解决“textType”的重用性问题,我们可以将keyref移动到“foo”定义中,选择器的xpath如下:.//xsfoo:term。所以,“textType”的定义是分裂的(所以,也许语义上不正确?),但它有效。

    完整的 XSD:

    <?xml version="1.0"?>
    <xs:schema
            xmlns:xs="http://www.w3.org/2001/XMLSchema"
            targetNamespace="foo"
            xmlns="foo"
            xmlns:xsfoo="foo"
            elementFormDefault="qualified">
    
        <xs:complexType name="textType" mixed="true">
            <xs:choice maxOccurs="unbounded">
                <xs:element name="term" minOccurs="0" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:simpleContent>
                            <xs:extension base="xs:normalizedString">
                                <xs:attribute name="ref" use="required" type="xs:token"/>
                            </xs:extension>
                        </xs:simpleContent>
                    </xs:complexType>
                </xs:element>
            </xs:choice>
        </xs:complexType>
    
        <xs:element name="foo">
            <xs:complexType>
                <xs:sequence>
    
                    <xs:element name="glossary">
                        <xs:complexType>
                            <xs:sequence>
                                <xs:element name="definition" minOccurs="0" maxOccurs="unbounded">
                                    <xs:complexType>
                                        <xs:complexContent>
                                            <xs:extension base="textType">
                                                <xs:attribute name="term" use="required" type="xs:token"/>
                                            </xs:extension>
                                        </xs:complexContent>
                                    </xs:complexType>
                                </xs:element>
                            </xs:sequence>
                        </xs:complexType>
                        <xs:unique name="glossaryTermUnique">
                            <xs:selector xpath="xsfoo:definition"/>
                            <xs:field xpath="@term"/>
                        </xs:unique>
                    </xs:element>
    
                </xs:sequence>
            </xs:complexType>
    
            <xs:keyref name="termRef" refer="glossaryTermUnique">
                <xs:selector xpath=".//xsfoo:term"/>
                <xs:field xpath="@ref"/>
            </xs:keyref>
    
        </xs:element>
    
    </xs:schema>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-28
      • 2020-12-28
      • 1970-01-01
      • 2016-12-28
      • 2020-09-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多