Reputation: 25
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
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() > 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