[xsl] tag and attribute statistics attached with node sequence

Subject: [xsl] tag and attribute statistics attached with node sequence
From: fatma helmy <fatmahelmy2000@xxxxxxxxx>
Date: Mon, 23 Apr 2007 08:44:33 -0700 (PDT)
Dear all
can i ask a question on XSLT ? pls, if this group is
not interested in xslt, would any one know the answer
reply me ? 
suppose i have the following xslt
<?xml version="1.0" encoding="UTF-8" ?>
<!--
<!DOCTYPE stylesheet
     PUBLIC "-//W3C//DTD XSLT 1.0//EN"
     "http://www.w3.org/1999/XSL/Transform";;>
-->
<xsl:stylesheet version="1.0"
           
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";;
            xmlns:lxslt="http://xml.apache.org/xslt";;
            xmlns:kite="http://www.kite.org.il";;
            xmlns:frequency="FrequenciesCounter"
            xmlns:auxiliary="Auxiliary"
            extension-element-prefixes="frequency
auxiliary">
  
  <!-- DistinctNamesCounter extension (Java) -->
  <lxslt:component prefix="frequency"
                   elements="" functions="incr
incrAttr count countPath countAttr countAttrValues
countAttrPerPath countAttrValuePerPath getTags
getDepths getPaths getAttrs getAttrValues
getAttrsPerPath getAttrValuesPerPath dumpDictionary">
    <lxslt:script lang="javaclass"
src="org.kite.dm.xslt.FrequenciesCounter"/>
  </lxslt:component>
  <lxslt:component prefix="auxiliary"
                   elements=""
functions="suppressWhitespace">
    <lxslt:script lang="javaclass"
src="org.kite.dm.Auxiliary"/>
  </lxslt:component>
  <!-- output format -->
  <xsl:output method="xml" indent="yes"
encoding="UTF-8" />
  <xsl:strip-space elements="*"/>
  <xsl:param name="dictionary" select="'dictionary'"/>
  <!-- template: root (real node from the first time)
-->
  <xsl:template match="/*">
    <!-- make a pass over the whole tree, calculating
    the frequencies -->
    <xsl:call-template name="calculate-frequencies" />
    <!-- get the frequencies in XML format, and sort
them -->
    <xsl:element name="frequencies">
      <xsl:call-template name="show-frequencies" />
    </xsl:element>
    
    <xsl:call-template name="dump-dictionary">
      <xsl:with-param name="dict-path"
select="$dictionary"/>
    </xsl:call-template>
  </xsl:template>
  
  <!-- make a pass over the whole tree, calculating
  the frequencies -->
  <xsl:template name="calculate-frequencies">
    <xsl:param name="depth" select="1"/>
    <!-- count the current tag's name -->
    <xsl:variable name="tagName" select="name()"/>
    <xsl:variable name="ignore"
select="frequency:incr($tagName,string($depth))"/>
    <!-- count current tag's attributes' values -->
    <xsl:for-each select="@*">
      <xsl:variable name="ignore"
select="frequency:incrAttr($tagName,name(),auxiliary:suppressWhitespace(string(.)))"/>
    </xsl:for-each>
    <!-- count current tag's text nodes -->
    <xsl:for-each select="text()">
      <xsl:variable name="text-rep"
select="auxiliary:suppressWhitespace(string(.))"/>
      <xsl:if test="not($text-rep = '')">
        <xsl:variable name="ignore"
select="frequency:incrAttr($tagName,concat('text-node-',position()),$text-rep)"/>
      </xsl:if>
    </xsl:for-each>
    <!-- descend to all the children -->
    <xsl:for-each select="*">
      <xsl:call-template name="calculate-frequencies">
        <xsl:with-param name="depth"
select="$depth+1"/>
      </xsl:call-template>
    </xsl:for-each>
  </xsl:template>
  <!-- give the frequencies in XML format -->
  <xsl:template name="show-frequencies">
    <xsl:for-each select="frequency:getTags()">
      <xsl:variable name="tag-name"
select="string(.)"/>
      <xsl:element name="tag">
        <xsl:attribute name="name">
          <xsl:value-of select="$tag-name" />
        </xsl:attribute>
        <xsl:attribute name="count">
          <xsl:value-of
select="frequency:count($tag-name)" />
        </xsl:attribute>
        <!-- produce frequencies per depths -->
        <xsl:call-template
name="show-frequencies-per-depth">
          <xsl:with-param name="tag-name"
select="$tag-name" />
        </xsl:call-template>
        <!-- produce paths per tag -->
        <xsl:call-template name="show-paths-per-tag">
          <xsl:with-param name="tag-name"
select="$tag-name" />
        </xsl:call-template>
        <!-- produce attrs per tag -->
        <xsl:call-template name="show-attrs-per-tag">
          <xsl:with-param name="tag-name"
select="$tag-name" />
        </xsl:call-template>
      </xsl:element>
    </xsl:for-each>
  </xsl:template>
  <!-- give the frequencies per depth -->
  <xsl:template name="show-frequencies-per-depth">
    <xsl:param name="tag-name" />
    <xsl:for-each
select="frequency:getDepths($tag-name)">
      <xsl:element name="tag-per-depth">
        <xsl:attribute name="depth">
          <xsl:value-of select="." />
        </xsl:attribute>
        <xsl:attribute name="count">
          <xsl:value-of
select="frequency:count($tag-name,string(.))" />
        </xsl:attribute>
      </xsl:element>
    </xsl:for-each>
  </xsl:template>
  <!-- give paths per tag -->
  <xsl:template name="show-paths-per-tag">
    <xsl:param name="tag-name" />
    <xsl:for-each
select="frequency:getPaths($tag-name)">
      <xsl:variable name="path" select="string(.)"/>
      
      <xsl:element name="path-per-tag">
        <xsl:attribute name="name">
          <xsl:value-of select="$tag-name" />
        </xsl:attribute>
        <xsl:attribute name="path">
          <xsl:value-of select="$path" />
        </xsl:attribute>
        <xsl:attribute name="count">
          <xsl:value-of
select="frequency:countPath($tag-name,string(.))" />
        </xsl:attribute>
        <!-- produce attrs per path -->
        <xsl:call-template
name="show-attrs-per-tag-path">
          <xsl:with-param name="tag-name"
select="$tag-name" />
          <xsl:with-param name="path" select="$path"/>
        </xsl:call-template>
      </xsl:element>
    </xsl:for-each>
  </xsl:template>
  <!-- give attrs per tag -->
  <xsl:template name="show-attrs-per-tag">
    <xsl:param name="tag-name"/>
    <xsl:for-each
select="frequency:getAttrs($tag-name)">
      <xsl:variable name="attr-name"
select="string(.)"/>
      
      <xsl:element name="attr-per-tag">
        <xsl:attribute name="name">
          <xsl:value-of select="$attr-name"/>
        </xsl:attribute>
        <xsl:attribute name="count">
          <xsl:value-of
select="frequency:countAttr($tag-name,$attr-name)"/>
        </xsl:attribute>
        <!-- produce attr values per attr -->
        <xsl:call-template
name="show-values-per-attr">
          <xsl:with-param name="tag-name"
select="$tag-name"/>
          <xsl:with-param name="attr-name"
select="$attr-name"/>
        </xsl:call-template>
      </xsl:element>
    </xsl:for-each>
  </xsl:template>
  <!-- give attr values per attr -->
  <xsl:template name="show-values-per-attr">
    <xsl:param name="tag-name"/>
    <xsl:param name="attr-name"/>
    <xsl:for-each
select="frequency:getAttrValues($tag-name,$attr-name)">
      <xsl:element name="value-per-attr">
        <xsl:attribute name="value">
          <xsl:value-of select="."/>
        </xsl:attribute>
        <xsl:attribute name="count">
          <xsl:value-of
select="frequency:countAttrValue($tag-name,$attr-name,string(.))"/>
        </xsl:attribute>
      </xsl:element>
    </xsl:for-each>
    
  </xsl:template>

  <!-- give attrs per tag per path -->
  <xsl:template name="show-attrs-per-tag-path">
    <xsl:param name="tag-name"/>
    <xsl:param name="path"/>
    <xsl:for-each
select="frequency:getAttrsPerPath($tag-name,$path)">
      <xsl:variable name="attr-name"
select="string(.)"/>
      
      <xsl:element name="attr-per-path">
        <xsl:attribute name="name">
          <xsl:value-of select="$attr-name"/>
        </xsl:attribute>
        <xsl:attribute name="count">
          <xsl:value-of
select="frequency:countAttrPerPath($tag-name,$attr-name,$path)"/>
        </xsl:attribute>
        <!-- produce attr values per attr -->
        <xsl:call-template
name="show-values-per-attr-path">
          <xsl:with-param name="tag-name"
select="$tag-name"/>
          <xsl:with-param name="attr-name"
select="$attr-name"/>
          <xsl:with-param name="path" select="$path"/>
        </xsl:call-template>
      </xsl:element>
    </xsl:for-each>
  </xsl:template>
  <!-- give attr values per attr per path -->
  <xsl:template name="show-values-per-attr-path">
    <xsl:param name="tag-name"/>
    <xsl:param name="attr-name"/>
    <xsl:param name="path"/>
    <xsl:for-each
select="frequency:getAttrValuesPerPath($tag-name,$attr-name,$path)">
      <xsl:element name="value-per-attr-per-path">
        <xsl:attribute name="value">
          <xsl:value-of select="."/>
        </xsl:attribute>
        <xsl:attribute name="count">
          <xsl:value-of
select="frequency:countAttrValuePerPath($tag-name,$attr-name,string(.),$path)"/>
        </xsl:attribute>
      </xsl:element>
    </xsl:for-each>
    
  </xsl:template>
  <xsl:template name="dump-dictionary">
    <xsl:param name="dict-path"/>
    <xsl:variable name="ignore"
select="frequency:dumpDictionary($dict-path)"/>
  </xsl:template>
</xsl:stylesheet>

the above xslt produces a statistics on tag counts
for example 
suppose i have this xml
<bookstore>
  <book>
          <author>  john  </author>   
  </book>
  <book>
         <author>  mary </author>
  </book>
</bookstore>

the following statistics will be
<tag> author </tag>
repeted twice in the path book/author
it has the following value john and mary
what i need is to add instruction that would give the
following
<tag> author </tag>
repeted twice in the path book/author
it has the following value john in the first book and
mary in the second book

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 

Current Thread