XPath用于XForm绑定约束中的唯一性检查

时间:2014-11-26 20:01:24

标签: xpath xforms

我正在尝试在XForm绑定中强制执行唯一性约束。相关的XML实例代码段为:

<PortAssignments>
  <PortAssignment>
    <PortReference IDREF="A">
    <PortReference IDREF="1">
    <Value>FOO</Value>
  </PortAssignment>
  <PortAssignment>
    <PortReference IDREF="A">
    <PortReference IDREF="1">
    <Value>BAR</Value>
  </PortAssignment>
  <PortAssignment>
    <PortReference IDREF="B">
    <PortReference IDREF="2">
    <Value>FOO2</Value>
  </PortAssignment>
</PortAssignments>

约束是每个端口只能连接到另一个唯一端口,因此在这种情况下,A必须始终连接到1,而B必须始终连接到2.但是,因为它们不必总之是独一无二的,我不能简单地检查没有重复,所以像下面这样的绑定不起作用。

<xf:bind ref="PortReference">
  <xf:bind ref="@IDREF" required="true" type="xs:string" constraint="not(. = ../../preceding-sibling::*/PortReference/@IDREF) and not(. = ../../following-sibling::*/PortReferenence/@IDREF)"/> 
</xf:bind>

我尝试过的另一件事是将绑定中的第二个PortReference与PortAssignment中的第二个PortReference与匹配的IDREF进行比较,但我无法找到一种方法来包含当前节点的上下文。这种查找的一个例子是:

<xf:bind ref="PortReference">
  <xf:bind ref="@IDREF" required="true" type="xs:string" constraint="not(../../../PortAssignment[PortReference/@IDREF = {binding node's IDREF}][rest of comparison])"/> 
</xf:bind>  

2 个答案:

答案 0 :(得分:0)

XPath中等效的{binding node's IDREF}context()函数。

您还可以确保唯一性计算值的发生次数(context()函数引用该值)

<xf:bind nodeset="/PortAssignments/PortAssignment/PortReference[1]/@IDREF"
  constraint="count( /PortAssignments/PortAssignment[PortReference[1]/@IDREF = context()] ) lt 2" />

答案 1 :(得分:0)

在看到Bill回答有关context()功能的回答后,我环顾四周,发现this discussion并意识到我可以将current()功能用于我的{binding node's IDREF}。这导致了以下XPath,它适用于任意数量的匹配PortReferences。

<xf:bind ref="PortAssignment/PortReference/@IDREF" constraint="not(boolean(../../preceding-sibling::*[PortReference[1]/@IDREF = current() and PortReference[2]/@IDREF != current()/../../PortReference[2]/@IDREF])) and not(boolean(../../following-sibling::*[PortReference[1]/@IDREF = current() and PortReference[2]/@IDREF != current()/../../PortReference[2]/@IDREF]))"/>