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

XML无法通过定义key/keyref的XSD验证,求技术支持

解决XSD中Keyref无法找到引用Key的问题

问题背景

使用Visual Studio 2022编辑并测试XML与XSD文件,需要实现Workload中的Package必须属于已定义的可用Package的验证逻辑。XSD本身可正常验证,但验证XML时,WorkloadPackage元素的Keyref约束报错,提示无法找到作用域内引用的key或unique,问题出在key和keyref的作用域及XPath选择器定义上。

报错信息

Warning The Keyref 'http://widgetcorp.com/test.xsd:WorkloadPackage' cannot find the referred key or unique in scope. config E:\kode\test.xml 7

问题分析

原XSD存在两个核心问题:

  1. 作用域不匹配:PackageKey定义在Package元素内部,作用域仅局限于单个Package节点;packageRef定义在WorkloadPackage元素内部,作用域仅局限于单个WorkloadPackage节点。两者不在同一作用域,导致keyref无法找到对应的key。
  2. 约束定义位置错误:key/keyref是针对整个文档的全局约束,应定义在根元素UbergenPackages下,而非子元素内部。

修正后的XSD代码

将xs:key和xs:keyref移动到根元素UbergenPackages的定义下,使其作用域覆盖整个文档,同时删除原元素内部的key/keyref定义:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://widgetcorp.com/test.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"   
    xmlns:ugpk="http://widgetcorp.com/test.xsd"
    elementFormDefault="qualified"
>
    <xs:element name="UbergenPackages">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="ugpk:Workloads" />
                <xs:element ref="ugpk:Packages" />
            </xs:sequence>
        </xs:complexType>
        <!-- 定义Package的唯一键,作用域覆盖整个UbergenPackages -->
        <xs:key name="PackageKey">
            <xs:selector xpath="ugpk:Packages/ugpk:Package"/>
            <xs:field xpath="@name"/>
        </xs:key>
        <!-- 定义WorkloadPackage对PackageKey的引用,作用域覆盖整个UbergenPackages -->
        <xs:keyref name="packageRef" refer="ugpk:PackageKey">
            <xs:selector xpath="ugpk:Workloads/ugpk:Workload/ugpk:WorkloadPackage"/>
            <xs:field xpath="@name"/>
        </xs:keyref>
    </xs:element>
                
    <xs:element name="Workloads">
        <xs:annotation>
            <xs:documentation>
                Workloads
            </xs:documentation>
        </xs:annotation>
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="ugpk:Workload" minOccurs="1" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="Workload">
        <xs:annotation>
            <xs:documentation>
                Workload
            </xs:documentation>
        </xs:annotation>
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="ugpk:WorkloadPackage" minOccurs="1" maxOccurs="unbounded" />
            </xs:sequence>
            <xs:attribute name="name" type="xs:string"/>
        </xs:complexType>
    </xs:element>

    <xs:element name="WorkloadPackage">
        <xs:annotation>
            <xs:documentation>
                Workload Package
            </xs:documentation>
        </xs:annotation>
        <xs:complexType>
            <xs:attribute name="name" type="xs:IDREF" use="required"/>
            <xs:attribute name="desc" type="xs:string" use="optional" />
            <xs:attribute name="loader" type="xs:string" use="optional" />
            <xs:attribute name="variable" type="xs:string" use="optional" />
        </xs:complexType>
    </xs:element>

    <xs:element name="Packages">
        <xs:annotation>
            <xs:documentation>
                Packages
            </xs:documentation>
        </xs:annotation>
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="ugpk:Package" minOccurs="1" maxOccurs="unbounded"></xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="Package">
        <xs:annotation>
            <xs:documentation>
                Package Details.  With mapping to OS and release/version.
            </xs:documentation>
        </xs:annotation>
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Module" minOccurs="1" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:attribute name="osname" type="xs:string" use="required"/>
                        <xs:attribute name="packageid" type="xs:string" use="required"/>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
            <xs:attribute name="name" type="xs:ID" use="required"/>
        </xs:complexType>
    </xs:element>

    <!-- Package Name -->
    <xs:simpleType name="PackageName">
        <xs:annotation>
            <xs:documentation>
                Package Name
            </xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:string">
            <xs:pattern value="([A-Za-z0-9][-_A-Za-z0-9]+)"/>
        </xs:restriction>
    </xs:simpleType>

</xs:schema>

验证效果

修改后,使用Visual Studio 2022验证原XML文件可正常通过:

  • 当WorkloadPackage的name属性值存在于Packages下的Package的name中时,验证通过;
  • 若WorkloadPackage引用了未定义的Package名称,会触发验证错误,符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 21:47:53