<?xml-stylesheet href="http://www.w3.org/StyleSheets/base.css" type="text/css"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns='http://www.w3.org/1999/xhtml'
  xmlns:html='http://www.w3.org/1999/xhtml'
  xmlns:wsn='http://www.w3.org/2005/09/checker/ws-normalize'
  xmlns:xdt='http://www.w3.org/2005/xpath-datatypes'
  exclude-result-prefixes="wsn html xdt xsl"
  version="2.0">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <link rel="stylesheet" href="http://www.w3.org/StyleSheets/base"/>
    <title>Recursive whitespace normalization</title>
    <style type="text/css">
      template, variable, param, tests { display: none }
    </style>
  </head>
  <body>
    <div class='head'><a href="/"><img src="/Icons/w3c_home" alt="W3C"/></a> </div>
    <h1>Recursive whitespace normalization</h1>

    <p>Determine whether two XML trees are same, having normalized
       space recursively.</p>

    <p class="copyright">Copyright &#169; 2006 <a href="http://www.w3.org/">World Wide Web Consortium</a>, (<a
href="http://www.csail.mit.edu/"><acronym title="Massachusetts Institute of
Technology">M.I.T.</acronym></a>, <a
href="http://www.ercim.org/"><acronym
title="European Research Consortium for Informatics and Mathematics">ERCIM</acronym></a>, <a
href="http://www.keio.ac.jp/">Keio University</a>). All Rights
    Reserved. http://www.w3.org/Consortium/Legal/. W3C <a href="http://www.w3.org/Consortium/Legal/copyright-software">software licensing</a> rules apply.</p>
    <address><a href="http://www.w3.org/People/Jacobs/">Ian Jacobs</a> - $Id: ws-normalize.xsl,v 1.13 2007/01/02 22:23:18 ijacobs Exp $</address>
    </body>
</html>

<tests xmlns="http://www.w3.org/2005/09/checker/ws-normalize">
  <test>
    <a>Same element and text</a>
    <a>Same element and text</a>
    <result>true</result>
  </test>
  <test>
    <a>Same element      but more spaces internally   </a>
    <a>   Same element but more spaces internally</a>
    <result>true</result>
  </test>
  <test>
    <a>One nested, the other not</a>
    <a><b>One nested, the other not</b></a>
    <result>false</result>
  </test>
  <test>
    <a attr="1">Same element and text and attrib and value</a>
    <a attr="1">Same element and text and attrib and value</a>
    <result>true</result>
  </test>
  <test>
    <a>Different element, same text</a>
    <b>Different element, same text</b>
    <result>false</result>
  </test>
  <test>
    <a>Same element, different text</a>
    <a>Different text, same element</a>
    <result>false</result>
  </test>
  <test>
    <a>Same element, different text</a>
    <a>Same element, different text since more</a>
    <result>false</result>
  </test>
  <test>
    <a attr="1">Same element, text, same attribute names</a>
    <a attr="1">Same element, text, same attribute names</a>
    <result>true</result>
  </test>
  <test>
    <a attr="1">Same element, text, same attribute names</a>
    <a attr2="1">Same element, text, diff attribute names</a>
    <result>false</result>
  </test>
  <test>
    <a attr="1" attr2="1">Different number attributes</a>
    <a attr2="1">Different number attributes</a>
    <result>false</result>
  </test>
  <test>
    <a attr="1">Different number attributes</a>
    <a attr2="1" attr3="2">Different number attributes</a>
    <result>false</result>
  </test>
  <test>
    <a attr="1" attr2="2">Different attribute values</a>
    <a attr="2" attr2="2">Different attribute values</a>
    <result>false</result>
  </test>
  <test>
    <a><b>Nested element</b></a>
    <a><b>Nested element</b></a>
    <result>true</result>
  </test>
  <test>
    <a><b>Nested element wrong</b></a>
    <a><c>Nested element wrong</c></a>
    <result>false</result>
  </test>
  <test>
    <a><b>Nested element</b></a>
    <a><b>Nested element</b><c>Second nested</c></a>
    <result>false</result>
  </test>
  <test>
    <a><b><c>Nested three</c></b></a>
    <a><b><c>Nested three</c></b></a>
    <result>true</result>
  </test>
  <test>
    <a><b><c>Nested three</c></b> Mixed</a>
    <a><b><c>Nested three</c></b> Mixed</a>
    <result>true</result>
  </test>
  <test>
    <a><b><c>Nested three</c></b> Mixed</a>
    <a><b><c>Nested three</c></b> Bad Mixed</a>
    <result>false</result>
  </test>
  <test>
    <a><b>Wrong</b><c>Order</c></a>
    <a><c>Wrong</c><b>Order</b></a>
    <result>false</result>
  </test>
  <test>
    <a><b><c attr="1">Nested three attrib</c></b> Mixed</a>
    <a><b><c attr="2">Nested three attrib</c></b> Mixed</a>
    <result>false</result>
  </test>
  <test>
    <a><b>B</b> Text</a>
    <a> Text <b>B</b></a>
    <result>false</result>
  </test>
  <test>
    <a><b><c>Nested three</c><d>testing extra space before element</d></b></a>
    <a><b><c>Nested three</c> <d>testing extra space before element</d></b></a>
    <result>true</result>
  </test>
  <test>
    <a><b></b></a>
    <a><b> </b></a>
    <result>true</result>
  </test>
</tests>

<!-- For the Unit Test -->
<xsl:template match="/">
  <xsl:message>Starting</xsl:message>
  <xsl:for-each select="document('')/xsl:stylesheet/wsn:tests/wsn:test">
      <xsl:message>Running test # <xsl:value-of select="position()"/> with tree1=<xsl:value-of select="*[position()=1]"/>; tree2=<xsl:value-of select="*[position()=2]"/>.</xsl:message>
    <xsl:variable name="output" select="deep-equal(wsn:deep-normalize-space(*[position()=1]),wsn:deep-normalize-space(*[position()=2]))"/>
    <xsl:choose>
      <xsl:when test="not($output=wsn:result)">

        <xsl:message>** failed: got <xsl:value-of select="$output"/>, expected <xsl:value-of select="wsn:result"/></xsl:message>
      </xsl:when>
      <xsl:otherwise>
        <xsl:message>success!</xsl:message>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:for-each>
</xsl:template>

<xsl:function name="wsn:deep-normalize-space">
  <xsl:param name="node" as="node()?"/>
  <xsl:apply-templates mode="normalize-ws" select="$node"/>
</xsl:function>

<xsl:function name="wsn:deep-strip-text">
  <xsl:param name="node" as="node()?"/>
  <xsl:apply-templates mode="ignore-text" select="$node"/>
</xsl:function>

<xsl:template match="text()" mode="normalize-ws">
  <xsl:value-of select=" normalize-space(translate(.,'&#xA0;',' ')) "/>
</xsl:template>

<xsl:template match="text()" mode="ignore-text"/>

<xsl:template match="*|@*" mode="normalize-ws">
  <xsl:copy>
    <xsl:apply-templates mode="normalize-ws" select="@*|node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="*|@*" mode="ignore-text">
  <xsl:copy>
    <xsl:apply-templates mode="ignore-text" select="@*|node()"/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>
