Как сослаться на другой экземпляр в итерации элемента действия XForms?

Я использую действие XForms вместе с iterate. iterate выбирает набор (используя XPath) узлов и повторяет действие для него. Проблема в том, что у меня есть несколько условий для выбора набора узлов.

  1. Не должно быть узла readOnly.
  2. Не должен быть частью списка ignoreProperties (этот список находится в другом экземпляре).

Код:

<xf:action ev:event="setValues" iterate="
    instance('allProps')/props/prop[
        not(readOnly) and
        not(instance('ignoreProperties')/ignoredProperties/property[text() = name]
    ]
">

Первое условие not(readOnly) работает. Но второе условие не работает. Я чувствую, что есть некоторая проблема с контекстом узлов XPath.

Как мне заменить второе условие для достижения результата?

Целевой XML — это простой ignoredProperties документ:

<ignoredProperties>
  <property>c_name</property>
  <property>c_tel_no</property>
</ignoredProperties>

person Crusaderpyro    schedule 28.09.2016    source источник


Ответы (2)


Это должно работать:

<xf:action ev:event="setValues" iterate="
    instance('allProps')/props/prop[
        not(readOnly) and
        not(name = instance('ignoreProperties')/ignoredProperties/property)
    ]
">

Оператор = работает с несколькими узлами, возвращая все совпадающие. С помощью not() вы можете выразить, что не хотите совпадения.

Явный выбор .../property/text() не требуется.

person Tomalak    schedule 28.09.2016
comment
К сожалению, это не сработало. Результат такой же, как и раньше. Свойства игнорирования по-прежнему являются частью результата. - person Crusaderpyro; 28.09.2016
comment
Опубликуйте XML, на который это нацелено. - person Tomalak; 28.09.2016
comment
Я добавил образец целевого XML. Однако я понял, что name = 'c_name' будет работать и даст результат с одним свойством, как и ожидалось, но not(name = 'c_name') не имеет никакого эффекта (ожидалось общее количество свойств -c_name). Вы уверены, что не часть? - person Crusaderpyro; 28.09.2016

Кажется, что-то не так с вашими звонками instance(). Если у вас есть:

<xf:instance id="ignoredProperties">
    <ignoredProperties>
        <property>c_name</property>
        <property>c_tel_no</property>
    </ignoredProperties>
</xf:instance>

Затем instance('ignoredProperties') возвращает элемент <ignoredProperties>. Итак, вы должны написать:

<xf:action ev:event="setValues" iterate="
    instance('allProps')/prop[
        not(readOnly) and
        not(instance('ignoreProperties')/property[text() = name])
    ]
">

Это также предполагает, что ваш экземпляр allProps имеет корневой элемент <props>.

Кроме того, второе условие кажется неверным, как уже показано в другом ответе. Вместо этого напишите:

not(name = instance('ignoreProperties')/property)

В XPath 2 вы могли бы уточнить, что ваши not() проверяют существование узла, используя вместо этого empty():

<xf:action ev:event="setValues" iterate="
    instance('allProps')/prop[
        empty(readOnly) and
        not(name = instance('ignoreProperties')/property)
    ]
">
person ebruchez    schedule 28.09.2016