You are viewing a plain text version of this content. The canonical link for it is here.
Posted to j-users@xalan.apache.org by Jan Hoeft <ma...@janhoeft.de> on 2009/06/18 14:29:23 UTC

xalan extensions - get the result tree

Hi,
is it possible to get the result tree and work on it?

I am able to do the transformation on my own via executeChildTemplates. 
But I have not found a way to process the result.

<xalan:component prefix="my" elements="countwords">
    <xalan:script lang="javascript">
        function countwords(context, elem){
            transf = context.getTransformer();
            transf.executeChildTemplates(elem,true);
            return "";
        }
    </xalan:script>
</xalan:component>

<xsl:template match="/">
    <my:countwords>
        <text>
            some words
            <xsl:value-of select="."/>
        </text>
    </my:countwords>
</xsl:template>

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?
Cheers
Jan


Re: xalan extensions - get the result tree

Posted by Michael Ludwig <ml...@as-guides.com>.
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>

Re: xalan extensions - get the result tree

Posted by David Bertoni <db...@apache.org>.
Jan Hoeft wrote:
> Hi,
> is it possible to get the result tree and work on it?
> 
> I am able to do the transformation on my own via executeChildTemplates. 
> But I have not found a way to process the result.
> 
> <xalan:component prefix="my" elements="countwords">
>    <xalan:script lang="javascript">
>        function countwords(context, elem){
>            transf = context.getTransformer();
>            transf.executeChildTemplates(elem,true);
>            return "";
>        }
>    </xalan:script>
> </xalan:component>
> 
> <xsl:template match="/">
>    <my:countwords>
>        <text>
>            some words
>            <xsl:value-of select="."/>
>        </text>
>    </my:countwords>
> </xsl:template>
Instead of doing this, I would create an extension function to count 
words, then do the following:

<xsl:template match="/">
   <xsl:variable name="text">
         some words
         <xsl:value-of select="."/>
   </xsl:variable>

   <text count="{ext:count-words($text)}">
     <xsl:value-of select="$text"/>
   </text>
</xsl:template?

If the whitespace within the "text" element is not interesting, you 
could create a string variable, instead of a result tree fragment variable:

   <xsl:variable name="text" select="concat('some words ', .)" />

which is more efficient.

Note that it's also possible to write a recursive template to count 
words, if you don't want to write an extension function.

Dave


Re: xalan extensions - get the result tree

Posted by Jan Hoeft <ma...@janhoeft.de>.
Hi Mukul,
I found a way to get the processed result as a string and count it:

function count(context, elem){
	transf = context.getTransformer();
	count=transf.transformToString(elem).length();

	transf.executeChildTemplates(elem,true);
	return "";
}

Is it possible to add an attribute to the parent node?
Thanks
Jan




Mukul Gandhi schrieb:
> Hi Jan,
>    Perhaps you can do this in two passes. In the first pass, you copy the tree:
>
> <text>
>    some words
>    some more words
> </text>
>
> in some variable. Then in second pass, you can find the count of words
> and create the required attribute.
>
> On Thu, Jun 18, 2009 at 5:59 PM, Jan Hoeft<ma...@janhoeft.de> wrote:
>   
>> Hi,
>> is it possible to get the result tree and work on it?
>>
>> I am able to do the transformation on my own via executeChildTemplates. But
>> I have not found a way to process the result.
>>
>> <xalan:component prefix="my" elements="countwords">
>>   <xalan:script lang="javascript">
>>       function countwords(context, elem){
>>           transf = context.getTransformer();
>>           transf.executeChildTemplates(elem,true);
>>           return "";
>>       }
>>   </xalan:script>
>> </xalan:component>
>>
>> <xsl:template match="/">
>>   <my:countwords>
>>       <text>
>>           some words
>>           <xsl:value-of select="."/>
>>       </text>
>>   </my:countwords>
>> </xsl:template>
>>
>> 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?
>> Cheers
>> Jan
>>     
>
>
>   


Re: xalan extensions - get the result tree

Posted by Mukul Gandhi <ga...@gmail.com>.
Hi Jan,
   Perhaps you can do this in two passes. In the first pass, you copy the tree:

<text>
   some words
   some more words
</text>

in some variable. Then in second pass, you can find the count of words
and create the required attribute.

On Thu, Jun 18, 2009 at 5:59 PM, Jan Hoeft<ma...@janhoeft.de> wrote:
> Hi,
> is it possible to get the result tree and work on it?
>
> I am able to do the transformation on my own via executeChildTemplates. But
> I have not found a way to process the result.
>
> <xalan:component prefix="my" elements="countwords">
>   <xalan:script lang="javascript">
>       function countwords(context, elem){
>           transf = context.getTransformer();
>           transf.executeChildTemplates(elem,true);
>           return "";
>       }
>   </xalan:script>
> </xalan:component>
>
> <xsl:template match="/">
>   <my:countwords>
>       <text>
>           some words
>           <xsl:value-of select="."/>
>       </text>
>   </my:countwords>
> </xsl:template>
>
> 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?
> Cheers
> Jan


-- 
Regards,
Mukul Gandhi