<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output encoding="iso-8859-1" method="text" version="1.0"/>

  <!-- pass the document's children to our converter -->
  <xsl:template match="/">
    COUNTS
    
      comment nodes:   <xsl:value-of select="count(//comment())"/>
      PI nodes:    <xsl:value-of select="count(//processing-instruction())"/>
      text nodes:    <xsl:value-of select="count(//text())"/>
      element nodes:   <xsl:value-of select="count(//*)"/>
      attribute nodes: <xsl:value-of select="count(//attribute::*)"/>
      namespace nodes: <xsl:value-of select="count(//namespace::*)"/>
    
    CONTENTS
    <xsl:call-template name="typechecker">
      <xsl:with-param name="nodes" select="//child::node() | //attribute::* | //namespace::*"/>
    </xsl:call-template>
  </xsl:template>

  <xsl:template name="typechecker">
    <xsl:param name="nodes"/>
    
    <!-- iterate through each node in given nodeset-->
    <xsl:for-each select="$nodes">
    
      <!-- act differently based on each node's type -->
      <xsl:choose>

        <!-- if current node's an attribute, report such -->  
        <xsl:when test="count(. | ../@*) = count(../@*)">
          attribute: <xsl:value-of select="name()"/>: <xsl:value-of select="."/>
        </xsl:when>        
        
        <!-- if current node's a comment, report such -->
        <xsl:when test="self::comment()">
          comment: <xsl:value-of select="."/>
        </xsl:when>

        <!-- if current node's a namespace, report such -->      
        <xsl:when test="count(. | ../namespace::*) = count(../namespace::*)">
          namespace: <xsl:value-of select="name()"/>: <xsl:value-of select="."/>
        </xsl:when>

        <!-- if current node's a PI, report such -->
        <xsl:when test="self::processing-instruction()">
          PI: <xsl:value-of select="name()"/>: <xsl:value-of select="."/>
        </xsl:when>

        <!-- if current node's text, report such -->
        <xsl:when test="self::text()">
          text: <xsl:value-of select="substring(., 0, 32)"/><xsl:if test="string-length(.) > 32">...</xsl:if>
        </xsl:when>
                
        <!-- if current node's an element, report such -->  
        <xsl:otherwise>
          element: <xsl:value-of select="name()"/>
        </xsl:otherwise>
        
      </xsl:choose>
      
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>
