tags:

views:

1558

answers:

4

For unknow reason max funtion doesn't work.

XML input file:

test.xml

<?xml version="1.0" encoding="UTF-8"?>
<numbers>
    <number>3</number>
    <number>5</number>
    <number>10</number>
    <number>1</number>
</numbers>

XSL input file

test.xsl

<?xml version="1.0"?>
<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:fn="http://www.w3.org/2005/02/xpath-functions"
    xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" >

    <xsl:output method="xml" indent="yes" />
    <xsl:template match="/numbers">
     <numbers>  
      <xsl:value-of select="/numbers/number" />     

      fn:max(2, 3)

     </numbers>
    </xsl:template> 

</xsl:stylesheet>

Output.xml

<?xml version="1.0" encoding="UTF-8"?>

<numbers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:fn="http://www.w3.org/2005/02/xpath-functions"&gt;3       

      fn:max(2, 3)


     </numbers>

Input file is not important here, but I would like to have '3' instead of fn:max(2, 3). How to do it?

for this XSL file:

<?xml version="1.0"?>

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:fn="http://www.w3.org/2005/02/xpath-functions"
    xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" >

    <xsl:output method="xml" indent="yes" />
    <xsl:template match="/numbers">
     <numbers>  
      <xsl:value-of select="/numbers/number" />     

      fn:max(2, 3)
      <xsl:value-of select="max(/numbers/number)"/>

     </numbers>
    </xsl:template> 

</xsl:stylesheet>

the following error occurs:

SystemId Unknown; Line #13; Column #49; Could not find function: max SystemId Unknown; Line #13; Column #49; function token not found. (Location of error unknown)java.lang.NullPointerException

(Location of error unknown)XSLT Error (javax.xml.transform.TransformerException) : No xml-stylesheet PI found in: test.xml Exception in thread "main" java.lang.RuntimeException: No xml-stylesheet PI foun d in: test.xml at org.apache.xalan.xslt.Process.doExit(Process.java:1155) at org.apache.xalan.xslt.Process.main(Process.java:1128)

I used Xalan - Version Xalan Java 2.7.1, Command: java org.apache.xalan.xslt.Process -in test.xml -xsl test.xsl -out output.xml

+2  A: 

You've put fn:max(2,3) in a text block. Nothing is going to interpret that. You need to put functions in value-of expressions if you want them to be evaluated.

Welbog
Do you mean something like this: <xsl:value-of select="max(/numbers/number)"/>it's not working
I mean <xsl:value-of select="fn:max(2,3)"/>
Welbog
+2  A: 

There are several problems: max() needs to be in a value-of, and that you've said xsl:stylesheet version="2.0" for Xalan, which only supports XSLT 1.0. For 2.0, you'd need Saxon 9.x.

Since max() isn't part of XSLT 1.0, you need to invoke the EXSLT extension support, which Xalan does have:

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:math="http://exslt.org/math"&gt;
    <xsl:template match="/numbers">
        <xsl:value-of select="math:max(number)"/>
    </xsl:template>
</xsl:stylesheet>

or

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:math="http://exslt.org/math"&gt;
    <xsl:template match="/">
        <xsl:value-of select="math:max(numbers/number)"/>
    </xsl:template>
</xsl:stylesheet>
lavinio
This also works for xsltproc
jrb
A: 

Lavino,

Thanks for the response. I don't know why but I was pretty sure that Xalan supports 2.0... I've tested it and it works for Saxon 9.

A: 

You can use

<xsl:value-of select="max(number)" />

to get the max of all numbers.

Soln:

<?xml version="1.0"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/02/xpath-functions" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/numbers">
     <numbers>
      <max>
       <xsl:value-of select="max(number)"/>
      </max>
      <xsl:apply-templates/>
     </numbers>
    </xsl:template>

    <xsl:template match="number">
     <number>
      <xsl:value-of select="."/>
     </number>
    </xsl:template>

</xsl:stylesheet>

You can omit the number template and <xsl:apply-templates/> if its not reqd. This will be the output with the above xslt:

<?xml version="1.0" encoding="UTF-8"?>
<numbers xmlns:fn="http://www.w3.org/2005/02/xpath-functions" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
    <max>10</max>
    <number>3</number>
    <number>5</number>
    <number>10</number>
    <number>1</number>
</numbers>
Rashmi Pandit