混淆错误消息“选择器或字段的无效XPath”

时间:2016-02-24 14:45:57

标签: c# xml xpath xsd

我正在尝试更好地理解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>

1 个答案:

答案 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