Фильтр Xpath, кроме текущей позиции () среди повторяющихся наборов узлов - PullRequest
0 голосов
/ 07 апреля 2011

В форме 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. Можно ли сделать то, что я спрашиваю? Я хочу сравнить текущий узел (скажем, 2-й набор в повторяющемся разделе) со всеми другими повторяющимися наборами узлов (в повторяющемся разделе 1 и 3), исключая текущий набор узлов (потому что, если вы сравниваете все, включая себя, он будет конечно, сравнивать с правдой).

1 Ответ

1 голос
/ 07 апреля 2011

Чтобы упростить вещи, я предположил, что у вас есть только один элемент для каждой итерации повтора:

<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>
...