我正在尝试在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>
答案 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]))"/>