Re: [xsl] Testing 2 XML documents for equality - a solution

Subject: Re: [xsl] Testing 2 XML documents for equality - a solution
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Thu, 31 Mar 2005 07:33:48 +1000
On Wed, 30 Mar 2005 07:28:39 -0800 (PST), Mukul Gandhi
<mukul_gandhi@xxxxxxxxx> wrote:
> Hello,
>  I was playing with XSLT. I thought could there be a
> nice way (with XSLT 1.0) to test 2 XML documents for
> equality. Two XML documents will be considered equal
> if all their nodes are identical(i.e. element, text,
> attribute, namespace etc).

This is not a precise definition of "document equality".

Trying to solve an imprecisely formulated problem is not a
well-founded and understood activity.

Generally, there is no solution to incorrectly formulated problems,
therefore lets return to solving real problems.


Cheers,
Dimitre Novatchev

> 
> I found few approaches for this in the FAQ (URL -
> http://www.dpawson.co.uk/xsl/sect2/N1777.html) .
> Indeed they are good work.. But I could come up with
> an elegant way. It uses no extension functions. Below
> is the XSLT ..
> 
> <?xml version="1.0"?>
> <xsl:stylesheet
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
> version="1.0">
> 
> <xsl:output method="text" />
> 
> <!-- parameter for "ignoring white-space only text
> nodes" during comparison -->
> <!-- if iws='y', "white-space only text nodes" will
> not be considered during comparison  -->
> <xsl:param name="iws" />
> 
> <xsl:variable name="doc1"
> select="document('file1.xml')" />
> <xsl:variable name="doc2"
> select="document('file2.xml')" />
> 
> <xsl:template match="/">
> 
>    <!-- store hash of 1st document into a variable;
>    it is concatination of name and values of all
> nodes -->
>    <xsl:variable name="one">
>      <xsl:for-each select="$doc1//@*">
>        <xsl:value-of select="name()" /><xsl:value-of
> select="." />
>      </xsl:for-each>
>      <xsl:choose>
>        <xsl:when test="$iws='y'">
>          <xsl:for-each
> select="$doc1//node()[not(normalize-space(self::text())
> = '')]">
>            <xsl:value-of select="name()"
> /><xsl:value-of select="." />
>          </xsl:for-each>
>        </xsl:when>
>        <xsl:otherwise>
>          <xsl:for-each select="$doc1//node()">
>            <xsl:value-of select="name()" /><xsl:value-of
> select="." />
>          </xsl:for-each>
>        </xsl:otherwise>
>      </xsl:choose>
>    </xsl:variable>
> 
>    <!-- store hash of 2nd document into a variable;
>    it is concatination of name and values of all
> nodes -->
>    <xsl:variable name="two">
>      <xsl:for-each select="$doc2//@*">
>        <xsl:value-of select="name()" /><xsl:value-of
> select="." />
>      </xsl:for-each>
>      <xsl:choose>
>         <xsl:when test="$iws='y'">
>           <xsl:for-each
> select="$doc2//node()[not(normalize-space(self::text())
> = '')]">
>             <xsl:value-of select="name()"
> /><xsl:value-of select="." />
>           </xsl:for-each>
>         </xsl:when>
>         <xsl:otherwise>
>           <xsl:for-each select="$doc2//node()">
>             <xsl:value-of select="name()"
> /><xsl:value-of select="." />
>           </xsl:for-each>
>         </xsl:otherwise>
>      </xsl:choose>
>    </xsl:variable>
>    <xsl:choose>
>      <xsl:when test="$one = $two">
>        Equal
>      </xsl:when>
>      <xsl:otherwise>
>        Not equal
>      </xsl:otherwise>
>    </xsl:choose>
> </xsl:template>
> 
> </xsl:stylesheet>
> 
> In this stylesheet, I am relying on 2 features -
> node() function and @* . node() function matches any
> node other than an attribute node and the root node.
> While @* matches any attribute. So I guess this XSLT
> can cater to all cases ;) . I have done limited
> testing with "element, text and attribute nodes only"
> and have got favourable results..
> 
> Another feature that I have incorporated in the
> stylesheet is, "controlling whether white space only
> text nodes should be considered during comparison".
> This is done with a stylesheet parameter iws. If it is
> "y", white space only text nodes will be ignored
> during comparison. If it is other than "y" or is not
> supplied, white space only text nodes will make a
> difference to the 2 documents.
> 
> If anybody cares to test this stylesheet and report
> any observations, I'll be happy!
> 
> Regards,
> Mukul
> 
> __________________________________
> Do you Yahoo!?
> Yahoo! Small Business - Try our new resources site!
> http://smallbusiness.yahoo.com/resources/

Current Thread