<?xml version='1.0'?>
<xsl:stylesheet version="1.0" 
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
	xmlns:msxsl="urn:schemas-microsoft-com:xslt"
	exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="/">
	<root>
		<test1>
			<xsl:variable name="compare">
				<xsl:call-template name="deep-diff">
					<xsl:with-param name="p1" select="books/book[1]"/>
					<xsl:with-param name="p2" select="books/book[2]"/>
				</xsl:call-template>
			</xsl:variable>
			<xsl:choose>
				<xsl:when test="count(msxsl:node-set($compare)/*) > 0">
					<xsl:copy-of select="$compare"/>
				</xsl:when>
				<xsl:otherwise>the nodes are equal</xsl:otherwise>
			</xsl:choose>
		</test1>
		
		<test2>
			<xsl:variable name="compare">
				<xsl:call-template name="deep-diff">
					<xsl:with-param name="p1" select="books/book[1]"/>
					<xsl:with-param name="p2" select="books/book[3]"/>
				</xsl:call-template>
			</xsl:variable>
		
			<xsl:choose>
				<xsl:when test="count(msxsl:node-set($compare)/*) > 0">
					<xsl:copy-of select="$compare"/>
				</xsl:when>
				<xsl:otherwise>the nodes are equal</xsl:otherwise>
			</xsl:choose>
		</test2>
	</root>
</xsl:template>

<xsl:template name="deep-diff">
<xsl:param name="p1"/>
<xsl:param name="p2"/>
		
	<xsl:for-each select="$p1/@*">
		<xsl:variable name="e1" select="."/>
		<xsl:variable name="e2" select="$p2/@*[namespace-uri($e1) = namespace-uri(.) and local-name($e1) = local-name(.)]"/>
		<xsl:if test="string($e1) != string($e2)">
			<diff>
				<item><xsl:copy-of select="$e1"/></item>
				<item><xsl:copy-of select="$e2"/></item>
			</diff>
		</xsl:if>
	</xsl:for-each>

	<xsl:for-each select="$p1/*">
		<xsl:variable name="pos" select="position()"/>
		<xsl:variable name="e1" select="."/>	
		<xsl:variable name="e2" select="$p2/*[namespace-uri($e1) = namespace-uri(.) and local-name($e1) = local-name(.) and position() = $pos]"/>
		<xsl:choose>
			<xsl:when test="count(*) = 0">
				<xsl:if test="string($e1) != string($e2)">
					<diff>
						<item position="{$pos}"><xsl:copy-of select="$e1"/></item>
						<item position="{$pos}"><xsl:copy-of select="$e2"/></item>
					</diff>
				</xsl:if>
			</xsl:when>
			<xsl:otherwise>
				<xsl:call-template name="deep-diff">
					<xsl:with-param name="p1" select="$e1"/>
					<xsl:with-param name="p2" select="$e2"/>
				</xsl:call-template>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:for-each>

</xsl:template>

</xsl:stylesheet><!-- Stylus Studio meta-information - (c) 2004-2006. Progress Software Corporation. All rights reserved.
<metaInformation>
<scenarios ><scenario default="yes" name="Scenario1" userelativepaths="yes" externalpreview="no" url="deep&#x2D;diff.xml" htmlbaseurl="" outputurl="" processortype="msxmldotnet" useresolver="no" profilemode="0" profiledepth="" profilelength="" urlprofilexml="" commandline="" additionalpath="" additionalclasspath="" postprocessortype="none" postprocesscommandline="" postprocessadditionalpath="" postprocessgeneratedext="" validateoutput="no" validator="internal" customvalidator=""/></scenarios><MapperMetaTag><MapperInfo srcSchemaPathIsRelative="yes" srcSchemaInterpretAsXML="no" destSchemaPath="" destSchemaRoot="" destSchemaPathIsRelative="yes" destSchemaInterpretAsXML="no"/><MapperBlockPosition></MapperBlockPosition><TemplateContext></TemplateContext><MapperFilter side="source"></MapperFilter></MapperMetaTag>
</metaInformation>
-->