Derek Ho
Derek Ho

Reputation: 25

XSL - How can I compare 2 sets of nodes?

I have the following data

<parent>
    <child>APPLES</child>
    <child>APPLES</child>
    <child>APPLES</child>
</parent>
<parent>
    <child>APPLES</child>
    <child>BANANA</child>
    <child>APPLES</child>
</parent>

Is there a simple way to compare the parent nodes? Or will I have to nest a for-each within a for-each and test every child manually with position()?

Upvotes: 2

Views: 3471

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167561

XSLT 2.0 has the function http://www.w3.org/TR/2013/CR-xpath-functions-30-20130521/#func-deep-equal so you could write a template

<xsl:template match="parent[deep-equal(., preceding-sibling::parent[1])]">...</xsl:template>

to process those parent elements that are equal to their preceding sibling parent.

If you want to do it with XSLT 1.0 then for your simple case of a sequence of child elements with plain text content it should suffice to write a template

<xsl:template match="parent" mode="sig">
  <xsl:for-each select="*">
    <xsl:if test="position() &gt; 1">|</xsl:if>
    <xsl:value-of select="."/>
  </xsl:for-each>
</xsl:template>

and then to use it as follows:

<xsl:template match="parent">
  <xsl:variable name="this-sig">
    <xsl:apply-templates select="." mode="sig"/>
  </xsl:variable>
  <xsl:variable name="pre-sig">
    <xsl:apply-templates select="preceding-sibling::parent[1]" mode="sig"/>
  </xsl:variable>
  <!-- now compare e.g. -->
  <xsl:choose>
    <xsl:when test="$this-sig = $pre-sig">...</xsl:when>
    <xsl:otherwise>...</xsl:otherwise>
  </xsl:choose>
</xsl:template>

For more complex content you would need to refine the implementation of the template computing a "signature" string, you might want to search the web, I am sure Dimitre Novatchev has posted solutions on earlier, similar questions.

Upvotes: 3

Related Questions