#xml #xpath #xforms #xpath-2.0
#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. Возможно ли сделать то, о чем я прошу? Я хочу сравнить текущий узел (скажем, 2-й набор повторяющегося раздела) со всеми другими повторяющимися наборами узлов (повторяющиеся разделы 1 и 3), исключая текущий набор узлов (потому что, если вы сравните со всеми, включая self, он, конечно, будет сравниваться как true).
Комментарии:
1. эргерон: Существует два подхода: использование предыдущей и следующей оси или использование выражения исключения (отрицание метода Кайсиана для пересечения). Значимая входная выборка позволила бы получить полный пример.
Ответ №1:
Чтобы упростить ситуацию, я предположил, что у вас есть только один элемент для каждой итерации repeat:
<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
ключевом слове, которое позволяет вам построить последовательность со всеми «другими повторяющимися значениями». Затем вы хотите знать, равен ли какой-либо из них текущему узлу, что вы делаете с помощью =
operator . Наконец, узел допустим, если вы не можете найти другой узел с тем же значением, следовательно 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>
Комментарии:
1. Потрясающе. Спасибо за разъяснение, лежащее в основе использования «except». В Интернете много информации, но у меня всегда возникают проблемы с отладкой этих проблем XPath. Я использовал ваш пример и проделал то же самое со своим кодом. Вот мой конечный результат
not(. = (../../repeated-section/dropdown except .))
Еще раз спасибо!