What is the best way to compare two elements in terms of their
attributes, and the attribute values? I need to ensure that each
element has the same number of attributes, the same attribute names and
the same attribute values.
Here's a simple way to do this (the separators must be well chosen not to be
a substring of the values of the attributes):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="x">
attributeEq(t, u) = <xsl:text/>
<xsl:call-template name="compAttributes">
<xsl:with-param name="pAtt1" select="t/@*"/>
<xsl:with-param name="pAtt2" select="u/@*"/>
</xsl:call-template>
attributeEq(t, v) = <xsl:text/>
<xsl:call-template name="compAttributes">
<xsl:with-param name="pAtt1" select="t/@*"/>
<xsl:with-param name="pAtt2" select="v/@*"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="compAttributes">
<xsl:param name="pAtt1" select="/.."/>
<xsl:param name="pAtt2" select="/.."/>
<xsl:choose>
<xsl:when test="count($pAtt1) = count($pAtt2)">
<xsl:variable name="v1">
<xsl:for-each select="$pAtt1">
<xsl:sort select="name()"/>
<xsl:value-of
select="concat('N', name(), 'N', 'V', ., 'V')"/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="v2">
<xsl:for-each select="$pAtt2">
<xsl:sort select="name()"/>
<xsl:value-of
select="concat('N', name(), 'N', 'V', ., 'V')"/>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="number($v1 = $v2)"/>
</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
When this thransformation is applied on the following source.xml:
<x>
<t a="xxx" b="yyy" c="zzz"/>
<u b="xxxT" a="yyy" c="zzz"/>
<v c="zzz" b="yyy" a="xxx"/>
</x>
the correct result is produced:
attributeEq(t, u) = 0
attributeEq(t, v) = 1
=====
Cheers,
Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list