Xpath过滤除重复节点集之外的所有当前位置()

时间:2011-04-06 22:21:16

标签: xml xpath xforms xpath-2.0

在XForms表单中,我有一个部分,其中包含输入。每个重复的部分都会有一个下拉列表,没有两个下拉列表可以选择相同的值。每个下拉列表必须具有唯一的选择,如果单独的部分中的下拉列表之间存在重复选择,则它们将变为无效。

这是我想要的想法

constraint="not(. = instance('my-instance')/repeated-section[Include everything BUT .'s parent]/dropdown)"

示例实例数据:

<repeated-section>
     <input1></input1>
     <input2></input2>
     <dropdown></dropdown>
     <input4></input4>
</repeated-section>    
<repeated-section>
     <input1></input1>
     <input2></input2>
     <dropdown></dropdown>
     <input4></input4>
</repeated-section>    
<repeated-section>
     <input1></input1>
     <input2></input2>
     <dropdown></dropdown>
     <input4></input4>
</repeated-section>

这主要是一个XPath过滤问题。有可能做我要问的事吗?我想比较当前节点(比如第二组重复节)与所有其他重复节点集(重复节1和3),不包括当前节点集(因为如果你比较所有包括自我,它将当然要比较真实)。

1 个答案:

答案 0 :(得分:1)

为简化起见,我假设重复的每次迭代只有一个元素:

<instance>
    <repeated-value>1</repeated-value>
    <repeated-value>2</repeated-value>
    <repeated-value>2</repeated-value>
</instance>

然后约束变为:

<xforms:bind ref="repeated-value" constraint="not(. = (../repeated-value except .))"/>

一个技巧是except关键字,它允许您构建一个包含所有“其他重复值”的序列。然后,您想知道其中任何一个是否等于当前节点,您使用=运算符。最后,如果您找不到具有相同值的另一个节点,则节点有效,因此not()。请注意,使用not(… = …)… != …不同。这是一个完整的例子来尝试这个:

<xhtml:html xmlns:xhtml="http://www.w3.org/1999/xhtml"
      xmlns:xforms="http://www.w3.org/2002/xforms"
      xmlns:xxforms="http://orbeon.org/oxf/xml/xforms"
      xmlns:ev="http://www.w3.org/2001/xml-events"
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      xmlns:fr="http://orbeon.org/oxf/xml/form-runner">
    <xhtml:head>
        <xhtml:title>No more than one</xhtml:title>
        <xforms:model>
            <xforms:instance>
                <instance>
                    <repeated-value>1</repeated-value>
                    <repeated-value>2</repeated-value>
                    <repeated-value>2</repeated-value>
                </instance>
            </xforms:instance>
            <xforms:bind ref="repeated-value" constraint="not(. = (../repeated-value except .))"/>
        </xforms:model>
        <xhtml:style type="text/css">
            .xforms-repeat-selected-item-1 { background: transparent }
            .xforms-input { display: block; padding-bottom: .5em  }
        </xhtml:style>
    </xhtml:head>
    <xhtml:body>
        <xforms:repeat ref="repeated-value">
            <xforms:input ref=".">
                <xforms:alert>This value is repeated more than once</xforms:alert>
            </xforms:input>
        </xforms:repeat>
    </xhtml:body>
</xhtml:html>