You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XSD中complexType内定义keyref出现找不到匹配键引用报错问题

问题背景

需要用XSD实现以下元素结构:

  • glossary
    • definition(term属性值唯一)
      • term(ref属性指向某条definition的term属性值)

具体规则:

  1. glossary可包含多条definition节点,每个definition的term属性唯一
  2. definition内部支持混合文本和term元素
  3. keyref(命名为termRef)需要作为textType这个complexType的公共能力,可在XSD多处复用,不止用于definition节点。

现有代码

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 test.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>

报错信息

Schemas validity error : Element '{foo}term': No match found for key-sequence ['ik 1'] of keyref '{foo}termRef'.


问题原因

核心问题是身份约束(key/keyref/unique)的定义位置不符合XSD规范:

  1. 身份约束只能作为元素声明(<xs:element>)的直接子元素,不能定义在全局complexType内部的局部元素声明下,你将termRef写在textType内部的term元素下,本身就是不合法的,导致约束作用域异常。
  2. 原来的glossaryTermUnique定义在glossary元素下,作用域仅覆盖glossary子树,和异常的termRef作用域不匹配,无法被引用。

修复方案

既满足textType复用需求,又符合XSD规范的修改如下:

  1. 删除textType内部term元素下的keyref定义
  2. 在根元素foo的声明下,同时定义unique和keyref约束,覆盖整个文档范围的definition和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:element>
            </xs:sequence>
        </xs:complexType>
        <!-- 全局唯一键,校验所有definition的term属性唯一 -->
        <xs:unique name="glossaryTermUnique">
            <xs:selector xpath="xsfoo:glossary/xsfoo:definition"/>
            <xs:field xpath="@term"/>
        </xs:unique>
        <!-- 全局键引用,校验所有term的ref属性指向存在的term值 -->
        <xs:keyref name="termRef" refer="glossaryTermUnique">
            <xs:selector xpath=".//xsfoo:term"/>
            <xs:field xpath="@ref"/>
        </xs:keyref>
    </xs:element>

</xs:schema>

修改后重新校验即可正常通过,同时textType可以任意复用到其他元素下,所有使用textType的元素中的term节点都会自动触发引用校验。


内容的提问来源于stack exchange,提问作者Raphhh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 07:57:02