[xslt] math:max and node-sets



Hi.

I ran into a problem concerning EXSLT math:max function (and maybe other
EXSLT functions handling node-sets) in combination with the
exsl:node-set function:

If $treefrag is a XML tree fragment, then calling 
math:max(exsl:node-set($treefrag)/*) returns NaN, while first converting
$treefrag to a node-set and applying math:max on the result (i.e.
$nodeset = exsl:node-set($treefrag), math:max($nodeset/*) ) works.
The same is true for math:min.
I did not test other EXSLT functions working on node-sets.

The attached example also includes another xsltproc misconduct:
xsltproc underestimates itself by returning false on
element-available(func:function) :)

xsltproc testcase10.xsl testcase.xml
Sorry, I don't support func:function
Largest number value: 300
Largest number value (computed by function foo:getMaxVal): 300
Largest number value (computed by function foo:getMaxVal2): NaN

xsltproc --version
Using libxml 20604, libxslt 10102 and libexslt 802
xsltproc was compiled against libxml 20604, libxslt 10102 and libexslt
802
libxslt 10102 was compiled against libxml 20604
libexslt 802 was compiled against libxml 20604

Cheers,

Markus
<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>

<!DOCTYPE xsl:stylesheet [

<!-- namespace for SVG -->
<!ENTITY svgns "http://www.w3.org/2000/svg";>
<!-- namespace for XSLT -->
<!ENTITY xsltns "http://www.w3.org/1999/XSL/Transform";>

<!-- namespaces for several EXSLT extension modules (see
     http://www.exslt.org for description) -->
<!ENTITY cns   "http://exslt.org/common";> <!-- EXSLT-Common -->
<!ENTITY fns   "http://exslt.org/functions";> <!-- EXSLT-Functions -->
<!ENTITY mns   "http://exslt.org/math";> <!-- EXSLT-Math -->

<!ENTITY foons "http://www.foo.org/bar";>

]>

<xsl:stylesheet version="1.0" 
                xmlns="&svgns;" 
                xmlns:xsl="&xsltns;"
                xmlns:exsl="&cns;"
                xmlns:func="&fns;"
                xmlns:math="&mns;"
                xmlns:foo="&foons;"
                extension-element-prefixes="exsl func math foo"
                exclude-result-prefixes="xsl exsl func math">

<xsl:output method="xml" indent="yes" encoding="iso-8859-1" standalone="yes"/>

<xsl:template match="/">
  <xsl:message>
    <xsl:choose>
      <xsl:when test="element-available('func:function')">
        <xsl:text>I support </xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text>Sorry, I don't support </xsl:text>
      </xsl:otherwise>
    </xsl:choose>
    <xsl:text>func:function&#10;</xsl:text>

    <xsl:text>Largest number value: </xsl:text>
    <xsl:value-of 
  select="math:max(rootelement/childelement/@val[string(number(.)) != 'NaN'])"/>
    <xsl:text>
Largest number value (computed by function foo:getMaxVal): </xsl:text>
    <xsl:value-of select="foo:getMaxVal(rootelement/childelement)"/>
    <xsl:text>
Largest number value (computed by function foo:getMaxVal2): </xsl:text>
    <xsl:value-of select="foo:getMaxVal2(rootelement/childelement)"/>
  </xsl:message>
</xsl:template>            

<func:function name="foo:getMaxVal">
  <xsl:param name="nodes"/>

  <xsl:variable name="resNodes">
    <xsl:for-each select="$nodes">
      <xsl:if test="@val and string(number(@val)) != 'NaN'">
        <dummynode>
          <xsl:value-of select="@val"/>
        </dummynode>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>

  <xsl:variable name="resNodeSet" select="exsl:node-set($resNodes)"/>
  
  <func:result select="math:max($resNodeSet/*)"/>
</func:function>

<func:function name="foo:getMaxVal2">
  <xsl:param name="nodes"/>

  <xsl:variable name="resNodes">
    <xsl:for-each select="$nodes">
      <xsl:if test="@val and string(number(@val)) != 'NaN'">
        <dummynode>
          <xsl:value-of select="@val"/>
        </dummynode>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>
  
  <func:result select="math:max(exsl:node-set($resNodes)/*)"/>
</func:function>

</xsl:stylesheet>
<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
<rootelement>
  <childelement val="300"/>
  <childelement val="100"/>
  <childelement val="200"/>
  <childelement val="300"/>
  <childelement val="nothing"/>
</rootelement>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]