How to filter a node list based on the contents of another node list

I would like to use XSLT to filter the node list based on the contents of another node list. In particular, I would like to filter out the node list so that elements with identical identification attributes are excluded from the resulting node list. Priority should be given to one of the two node lists.

The way I originally assumed it to be implemented is to do something like this:

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

The problem is that the node context changes in the predicate for $ list2, so I don't have access to the @ id_from_list1 attribute. Due to these limitations, the limitations are unclear how I could refer to an attribute from an external node list using nested predicates in this way.

To get around the node context issue, I tried to create a solution that included a for-each loop, as shown below:

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

But this does not work correctly. I also don't understand how this fails ... Using the above technique, filterList1 has a length of 1, but seems empty. This is a strange behavior, and in any case, I feel that there should be a more elegant approach.

I would be grateful for any guidance that anyone can offer. Thank.

+3
source share
2 answers

Use this single line XPath layer :

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

+3
source

As far as I know, using the syntax $ var [] does not work. What works: expr1 / [expr2 = $ var] and func1 ($ var).

What you can do is simply insert the expression that gives $ list2 in the if test:

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

+1

Source: https://habr.com/ru/post/1748953/


All Articles