Xml &引用;“项目太多”;使用XPath eq运算符进行断言

Xml &引用;“项目太多”;使用XPath eq运算符进行断言,xml,xpath,xsd,xpath-2.0,Xml,Xpath,Xsd,Xpath 2.0,我在根据XML模式验证以下XML文件时遇到问题。错误是“提供了太多预期为“1”、“3”的项。在断言中,我想表示以下内容:每当OID值等于BOID值时,A_隶属度应大于或等于B_隶属度 示例XML X1 D1 G1 一层楼 G2 地上二层 X2 D2 G3 F3 G4 F4 X11 D11 当前模式 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vc="http://www.w3.org/

我在根据XML模式验证以下XML文件时遇到问题。错误是“提供了太多预期为“1”、“3”的项。在断言中,我想表示以下内容:每当OID值等于BOID值时,A_隶属度应大于或等于B_隶属度

示例XML


X1
D1
G1
一层楼
G2
地上二层
X2
D2
G3
F3
G4
F4
X11
D11
当前模式

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
           xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" 
           elementFormDefault="qualified" 
           attributeFormDefault="unqualified" 
           vc:minVersion="1.1">
  <xs:element name="Document">
    <xs:complexType>
      <xs:sequence maxOccurs="unbounded">
        <xs:element ref="A" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="B" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="C" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:assert 
        test="if(.//@OID eq  .//@BOID) 
              then ./A/@A_Membership_Degree  
                   ge ./B/@B_Membership_Degree else false()"/>
    </xs:complexType>
    <xs:key name="aKey">
      <xs:selector xpath="A"/>
      <xs:field xpath="@OID"/>
    </xs:key>
    <xs:keyref name="aKeyRef" refer="aKey">
      <xs:selector xpath="./B"/>
      <xs:field xpath="@BOID"/>
    </xs:keyref>
    <xs:keyref name="aKeyRef1" refer="aKey">
      <xs:selector xpath="./C"/>
      <xs:field xpath="@COID"/>
    </xs:keyref>
  </xs:element>
  <xs:element name="A" type="Atype"/>
  <xs:complexType name="Atype">
    <xs:sequence minOccurs="0" maxOccurs="unbounded">
      <xs:element name="A1" type="xs:string" minOccurs="1" maxOccurs="1"/>
      <xs:element name="A2" type="xs:string" minOccurs="1" maxOccurs="1"/>
    </xs:sequence>
    <xs:attribute name="OID" type="xs:string" use="required"/>
    <xs:attribute name="A_Membership_Degree" type="FuzzyValue" use="optional"/>
    <xs:attribute name="D_Membership_Degree" type="FuzzyValue" use="optional"/>
  </xs:complexType>
  <xs:element name="B" type="Btype"/>
  <xs:complexType name="Btype">
    <xs:sequence>
      <xs:element name="B1" type="xs:string" minOccurs="1" maxOccurs="1"/>
      <xs:element name="B2" type="xs:string" minOccurs="1" maxOccurs="1"/>
    </xs:sequence>
    <xs:attribute name="BOID" type="xs:string" use="required"/>
    <xs:attribute name="B_Membership_Degree" type="FuzzyValue" use="optional"/>
  </xs:complexType>
  <xs:element name="C" type="Ctype"/>
  <xs:complexType name="Ctype">
    <xs:sequence>
      <xs:element name="C1" type="xs:string" minOccurs="1" maxOccurs="1"/>
      <xs:element name="C2" type="xs:string" minOccurs="1" maxOccurs="1"/>
    </xs:sequence>
    <xs:attribute name="COID" type="xs:string" use="required"/>
    <xs:attribute name="C_Membership_Degree" type="FuzzyValue" use="required"/>
  </xs:complexType>
  <xs:simpleType name="FuzzyValue">
    <xs:restriction base="xs:decimal">
      <xs:minInclusive value="0"/>
      <xs:maxInclusive value="1"/>
    </xs:restriction>
  </xs:simpleType>
</xs:schema>

在XPath条件表达式中,
else
子句不是可选的。因此添加
else false()
可能是最简单的修复方法

一些读者(包括我)可能会发现将断言重新表述为一个明显的布尔值更为清晰:

not(.//@OID eq .//@BOID)
or
(./A/@Membership_Degree ge ./B/@A_Membership_Degree)

但是清晰往往是旁观者的眼睛;你应该用你和你的代码的预期读者认为最清晰的习惯用法来写。

这个特定错误的原因是
eq
ge
操作符期望它们的参数是单个值,但是你给它们提供了一组多个节点。而不是简单
如果
您需要这样一个明确的量化表达式

every $a in A, $b in B[@BOID eq $a/@OID] satisfies
    $a/@A_Membership_Degree ge $b/@B_Membership_Degree

子句中的
对基本上会生成一个包含所有a和B对的列表,其中a和B对具有匹配ID,
满足
子句会检查每对的成员资格条件。

错误消息到底是什么?您能给出一些应该有效和无效的XML文档的示例吗?您使用的模式是iven允许任何数字,如果A和B元素,那么您要比较哪个ID?全部与全部?顺便说一句,在未来,尝试将您的问题减少到再现您所问问题的最小内容(但请测试您发布的内容是否仍然可以运行并生成您的问题!)。请参阅,我已将预期的XML验证文件添加到问题中。在assert中,我要表达以下内容:每当OID值等于BOID值时,A_Membership_Degree应大于或等于B_Membership_Degree我还有一个问题,如果我要表达以下内容,我应该在assert语句中写些什么:在XML文件中,whe从不显示A节点,则B节点或C节点或两者都应显示为OID eq BOID和OID eq COID。基本上,对于提供的XML,OID=HHH的最后一个A节点不应出现。@Reema堆栈溢出的工作方式是,最好将不同的问题作为单独的SO问题而不是注释提问。如果您满意请将您的原始问题的其中一个答案替换为“已接受”,然后单击左侧的勾号将其标记为“已接受”,然后针对您的新问题提出一个新问题。对不起,我不知道。我将添加一个新问题。