Как отфильтровать список узлов на основе содержимого списка других узлов - PullRequest
4 голосов
/ 08 июня 2010

Я хотел бы использовать XSLT для фильтрации списка узлов на основе содержимого другого списка узлов. В частности, я хотел бы отфильтровать список узлов так, чтобы элементы с идентичными атрибутами id были исключены из результирующего списка узлов. Приоритет должен быть отдан одному из двух списков узлов.

То, как я изначально представлял себе это, было сделать что-то вроде этого:

<xsl:variable name="filteredList1" select="$list1[not($list2[@id_from_list1 = @id_from_list2])]"/>

Проблема в том, что контекстный узел изменяется в предикате для $ list2, поэтому у меня нет доступа к атрибуту @ id_from_list1. Из-за этих ограничений области видимости мне не ясно, как я мог бы ссылаться на атрибут из списка внешних узлов, используя вложенные предикаты таким способом.

Чтобы обойти проблему узла контекста, я попытался создать решение, включающее цикл for-each, например:

    <xsl:variable name="filteredList1"> 
        <xsl:for-each select="$list1">
            <xsl:variable name="id_from_list1" select="@id_from_list1"/>

            <xsl:if test="not($list2[@id_from_list2 = $id_from_list1])">
                <xsl:copy-of select="."/>
            </xsl:if>
        </xsl:for-each>
    </xsl:variable>

Но это не работает правильно. Мне также непонятно, как происходит сбой ... Используя описанную выше технику, FilterList1 имеет длину 1, но кажется пустым. Это странное поведение, и в любом случае, я чувствую, что должен быть более элегантный подход.

Буду признателен за любые рекомендации, которые может предложить любой. Спасибо.

Ответы [ 2 ]

4 голосов
/ 08 июня 2010

Используйте этот однострочный XPath :

$vList1[not(@id = $vList2/@id)]

1 голос
/ 08 июня 2010

Насколько я знаю, использование синтаксиса $ var [] не работает. Что работает: expr1 / [expr2 = $ var] и func1 ($ var).

Что вы можете сделать, это просто вставить выражение, которое возвращает $ list2 в тесте if:

<xsl:for-each select="$list1">
  <xsl:variable name="id" select="@id_from_list1"/>
  <xsl:if test="not(expr2[@id_from_list2 = $id ])">
    <xsl:copy-of select="."/>
  </xsl:if>
</xsl:for-each>
<xsl:copy-of select="$list2"/>

Замените expr2 фактическим выражением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...