XML 未针对定义了密钥和 keyref 的 XSD 进行验证

问题描述 投票:0回答:1

获取 XML 文件以针对 XSD 进行验证时遇到问题。 我正在使用 Visual Studio 2022 编辑和测试 XML 和 XSD。

尝试验证工作负载中的包是已知可用包之一。

XSD 本身会验证,但是当尝试使用 XSD 验证 XML 时,我从 WorkloadPackage 元素的 Keyref 约束中收到错误。

我相信问题出在 key 和/或 keyref xpath 选择器规范上。

感谢您的帮助!

收到的错误是:

  • 警告 Keyref 'http://widgetcorp.com/test.xsd:WorkloadPackage' 找不到引用的键或唯一的 范围。配置 E:\kode est.xml 7

XSD(测试.xsd):

<?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>
    </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: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="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:key name="PackageKey">
            <xs:selector xpath="ugpk:Packages/ugpk:Package"/>
            <xs:field xpath="@name"/>
        </xs:key>
    </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>

XML(测试.xml):

<?xml version="1.0" encoding="utf-8"?>
<UbergenPackages xmlns="http://widgetcorp.com/test.xsd"
               xmlns:ugpk="http://widgetcorp.com/test.xsd" >

    <Workloads>
        <Workload name="prerequisites">
            <WorkloadPackage name="aanotify"                                desc="Virtualization"/>
            <WorkloadPackage name="aatools"                                 desc="Network"/>
        </Workload>
        <Workload name="libreoffice">
            <WorkloadPackage name="libreoffice"     variable="true"         desc="Libre Office" />
        </Workload>
    </Workloads>

    <Packages>
        <Package name="aatools">
            <Module osname="Debian"         packageid="apparmor-easyprof" />
            <Module osname="Ubuntu"         packageid="apparmor-easyprof" />
        </Package>
        <Package name="aanotify">
            <Module osname="Debian"         packageid="aanotify" />
            <Module osname="Ubuntu"         packageid="aanotify" />
        </Package>
        <Package name="libreoffice">
            <Module osname="Debian"         packageid="aautils" />
            <Module osname="Ubuntu"         packageid="aautils-new" />
        </Package>
    </Packages>
    
</UbergenPackages>  
xml xsd xsd-validation xml-validation
1个回答
0
投票

根据您提供的错误消息,您的 test.xsd 中的密钥或 keyref xpath 选择器规范似乎存在问题

要验证工作负载中的包是已知可用包之一,您需要使用键和键引用组合。这是您可以执行此操作的方法:

<xs:key name="packageKey">
  <xs:selector xpath="./Packages/Package"/>
  <xs:field xpath="@name"/>
</xs:key>

此键指定 XML 中每个 Package 元素的“名称”属性的值是唯一的。

在 XSD 中定义一个引用键的 keyref,并为应该引用键的元素指定选择器

<xs:keyref name="packageRef" refer="ugpk:packageKey">
 <xs:selector xpath="./Workloads/Workload/WorkloadPackage"/>
 <xs:field xpath="@name"/>
</xs:keyref>

此 keyref 指定 XML 中每个 WorkloadPackage 元素上的“name”属性值应与 Package 元素上的“name”属性值之一匹配。

请注意,在这两种情况下,“xpath”属性都指定了 XML 中相关元素的路径。

在 XSD 中使用这些键和 keyref 定义,您应该能够验证 WorkloadPackage 元素的 Package 属性是否与已知的可用包之一匹配。

© www.soinside.com 2019 - 2024. All rights reserved.