Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XSLT User Defined Function

Tags:

xml

xslt

xslt-2.0

I am new to XSLT 2.0. I am intrigued by User Defined functions ( <xsl:function ). In particular, I'd like to use a UDF to make the code more modular and readable.

I have this xsl:

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet
   version="2.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
    <xsl:variable name="stopwords"
        select="document('stopwords.xml')//w/string()"/>
             <wordcount>
                <xsl:for-each-group group-by="." select="
                    for $w in //text()/tokenize(., '\W+')[not(.=$stopwords)] return $w">
                    <xsl:sort select="count(current-group())" order="descending"/>            
                    <word word="{current-grouping-key()}" frequency="{count(current-group())}"/>
                </xsl:for-each-group>
             </wordcount>
</xsl:template>
</xsl:stylesheet>

Can want to add more condition testing (for example, exclude digits) to the for $w in //text()/tokenize(., '\W+')[not(.=$stopwords)] but the code would get messy.

Is a UDF an option to tidy up that section of code if I make it more complex. Is it good practice to do so?

like image 328
Paulb Avatar asked Aug 17 '13 13:08

Paulb


People also ask

How do I write a function in XSLT?

Add the <msxsl:script> element to the template's markup within which you will add your C# functions. Add the function within the <msxsl:script> element. Keep all your functions within a CDATA element. Now you can directly call the C# function in your XSLT prefixing its name with “csharp” namespace.

What is the function of XSLT?

The XSLT function returns the element that contains the current node. This function is necessary for accessing the current node when it is not the same as the context node provided in the code because both the nodes are the same.

What is text () in XSLT?

XSLT <xsl:text> The <xsl:text> element is used to write literal text to the output. Tip: This element may contain literal text, entity references, and #PCDATA.

What is current () XSLT?

XSLT current() Function The current() function returns a node-set that contains only the current node. Usually the current node and the context node are the same.


1 Answers

Well you could write a function to be used in the predicate

<xsl:function name="mf:check" as="xs:boolean">
  <xsl:param name="input" as="xs:string"/>
  <xsl:sequence select="not($input = $stopwords) and not(matches($input, '^[0-9]+$'))"/>
</xsl:function>

and use it in your code e.g.

<xsl:stylesheet
   version="2.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
   xmlns:mf="http://example.com/mf"
   exclude-result-prefixes="mf xs">
<xsl:output method="xml" indent="yes"/>

    <xsl:function name="mf:check" as="xs:boolean">
      <xsl:param name="input" as="xs:string"/>
      <xsl:sequence select="not($input = $stopwords) and not(matches($input, '^[0-9]+$'))"/>
    </xsl:function>

    <xsl:variable name="stopwords"
        select="document('stopwords.xml')//w/string()"/>

    <xsl:template match="/">
        <wordcount>
            <xsl:for-each-group group-by="." select="
                for $w in //text()/tokenize(., '\W+')[mf:check(.)] return $w">
                <xsl:sort select="count(current-group())" order="descending"/>            
                <word word="{current-grouping-key()}" frequency="{count(current-group())}"/>
            </xsl:for-each-group>
        </wordcount>
    </xsl:template>
</xsl:stylesheet>
like image 100
Martin Honnen Avatar answered Sep 18 '22 17:09

Martin Honnen