Jan Hoeft schrieb:
Hi,
is it possible to get the result tree and work on it?

Moin Jan,

yes, it is possible.

my xml file:

<root>
    some more words
</root>

What i am trying to do is to add an attribute count to the text output.

<text count="5">
     some words
     some more words
</text>

Any idea how to do this?

You could post-process the result tree of your first transformation
using a second transformation that would only add the @count.

You'd need some criterion to determine what elements to do the count on
and what to count in each case, children or descendants.

You'd then need some means to do the counting. You could use str:split
or str:tokenize (EXSLT) [1], or an extension function written in
JavaScript [2] (see attached example) or Java [3].

[1] http://exslt.org/str/index.html
[2], [3] http://xml.apache.org/xalan-j/extensions.html

To run the following you need xalan.jar, bsf.jar (Bean Scripting
Framework), js.jar (Rhino), and commons-logging.jar on the classpath.

Michael Ludwig

<xsl:stylesheet version="1.0"
  xmlns:xalan="http://xml.apache.org/xalan";
  xmlns:milu="urn:X-MiLu"
  extension-element-prefixes="milu"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

  <!-- See http://xml.apache.org/xalan-j/extensions.html -->
  <xalan:component prefix="milu" functions="wordCount">
    <xalan:script lang="javascript"><![CDATA[
      var tokenizer = new RegExp( '\\W+');
      function countWords( str) {
        ary = str.split( tokenizer);
        ary2 = new Array(); // eliminate empty strings
        for ( i = 0; i < ary.length; i++ ) {
          if ( ary[i].length == 0 ) continue;
          ary2.push(ary[i]);
        }
        return ary2.length;
      }
      ]]></xalan:script>
  </xalan:component>

  <xsl:template match="*" priority="-0.4"><!-- elements go here -->
    <xsl:copy><!-- copy, add attributes -->
      <xsl:attribute name="wc-descendants">
        <xsl:value-of select="milu:countWords( normalize-space(.))"/>
      </xsl:attribute>
      <xsl:attribute name="wc-children">
        <xsl:value-of select="milu:countWords( normalize-space( text()))"/>
      </xsl:attribute><!-- then continue processing as usual -->
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

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

</xsl:stylesheet>

Reply via email to