我正在尝试更好地理解key和keyref以及如何在架构中使用它们。我想将一个键应用于y类型的部分,而不是z类型的部分。我很困惑为什么我看到以下错误。
'r:B / r:part [@ type ='y']'是选择器或字段的无效XPath
我几乎可以肯定XPath是有效的,但是一旦我在XPath表达式中输入谓词过滤器,我就会从Visual Studio中收到错误。
这是XML
<root xmlns="namespace1">
<A>
<!-- if the ref-number is not equal to one of the key-number, the validation will give error -->
<part ref-number="1"/>
</A>
<A>
<!-- if the ref-number is not equal to one of the key-number, the validation will give error -->
<part ref-number="2"/>
</A>
<B>
<part type="y" key-number="1"/>
<part type="y" key-number="2"/>
<part type="z" key-number="3"/>
</B>
</root>
这是架构
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="namespace1" xmlns:r="namespace1" elementFormDefault="qualified">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="A" type="r:aType" maxOccurs="unbounded">
<xs:keyref name="dummy" refer="r:partNumberKey">
<xs:selector xpath="r:part"/>
<xs:field xpath="@ref-number"/>
</xs:keyref>
</xs:element>
<xs:element name="B" type="r:bType"/>
</xs:sequence>
</xs:complexType>
<xs:key name="partNumberKey">
<!-- I get an error here -->
<xs:selector xpath="r:B/r:part[@type='y']"/>
<xs:field xpath="@key-number"/>
</xs:key>
</xs:element>
<xs:complexType name="aType">
<xs:sequence>
<xs:element name="part" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="ref-number" type="xs:integer"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="bType">
<xs:sequence>
<xs:element name="part" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="key-number" type="xs:integer"/>
<xs:attribute name="type" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
答案 0 :(得分:2)
您从Xerces / Oxygen获得更有意义的错误消息:
[Xerces] c-general-xpath:表达式&#39; r:B / r:part [@type =&#39; y&#39;]&#39;对于XML Schema支持的XPath子集无效。
XML Schema仅支持subset of XPath。以下规则列出了允许的内容作为xpath
的{{1}}属性的值:
xs:selector
在这种情况下,支持带谓词的表达式(在[1] Selector ::= Path ( '|' Path )*
[2] Path ::= ('.//')? Step ( '/' Step )*
[3] Step ::= '.' | NameTest
[4] NameTest ::= QName | '*' | NCName ':' '*'
和[
之间)不是一种神秘的方式。
如果您自己设计了此XML,则可以为]
元素指定不同的名称,而不是part
个不同的属性。
另一种方法是在XML Schema中包含一个执行此检查的Schematron规则。
使用嵌入式Schematron修改的XML架构
type
我不确定这正是您想要的,因为我不完全理解为什么<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:r="namespace1"
xmlns:sch="http://purl.oclc.org/dsdl/schematron"
targetNamespace="namespace1"
elementFormDefault="qualified">
<xs:annotation>
<xs:appinfo>
<sch:ns uri="namespace1"
prefix="r" />
<sch:pattern>
<sch:rule context="r:A/r:part">
<sch:assert test="@ref-number = /r:root/r:B/r:part/@key-number">Key Error!</sch:assert>
</sch:rule>
</sch:pattern>
</xs:appinfo>
</xs:annotation>
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="A" type="r:aType" maxOccurs="unbounded"/>
<xs:element name="B" type="r:bType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="aType">
<xs:sequence>
<xs:element name="part" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="ref-number" type="xs:integer"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="bType">
<xs:sequence>
<xs:element name="part" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="key-number" type="xs:integer"/>
<xs:attribute name="type" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
元素的type
属性很重要。
如果您在XML实例文档中引用XSD,那么您现在还需要包含Schematron规则的引用,
part