[xslt] extension function + xsl:sort do not work



I have follwing custom function:

// convert IPv4 address (string) to number
static void xslIp2Number(xmlXPathParserContextPtr ctxt, int nargs)
{
  xsltTransformContextPtr tctxt = getContext(ctxt);
  if (!tctxt) return;
  xmlChar *xstr = xmlXPathPopString(ctxt);

  struct in_addr ad;
  if(inet_aton((char *)xstr, &ad) == 1) {
        unsigned long num = (unsigned long)ntohl(ad.s_addr);
        valuePush(ctxt, xmlXPathNewFloat((double)num));
  } else
        valuePush(ctxt, xmlXPathNewNodeSet(NULL));

  xmlFree(xstr);
}

And following XSLT code:

<xsl:stylesheet version="1.0" extension-element-prefixes="my exsl"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
  xmlns:exsl="http://exslt.org/common";
  xmlns:my="http://www.fsb.ru/xslt/my";
  >

  <xsl:output method="html"/>

  <xsl:template match="/">
        <xsl:for-each select="//ip">
                <xsl:sort select="my:ip2number(.)" data-type="number"/>
                <xsl:value-of select="format-number(my:ip2number(.),
'#;-#')"/> -&#09;<xsl:value-of select="."/>;
        </xsl:for-each>

  </xsl:template>

</xsl:stylesheet>

With this incoming document:
<ips>
        <ip>2.2.2.2</ip>
        <ip>1.1.1.1</ip>
        <ip>200.200.200.200</ip>
</ips>


It do bad sorting output:
-----
3368601800 -    200.200.200.200;
  16843009 -      1.1.1.1;
  33686018 -      2.2.2.2;
-----
(first line should be last)

I have tried to debug this - xslIp2Number() push valid number into
stack.

Looks like bug in xsl:sort

More details:

Red Hat Linux release 9 (Shrike)

libxslt-1.1.7-1.1.swsoft
libxml2-2.6.9-1
gcc-3.2.2-5

PS:
running same code on FreeBSD-6-CURRENT with libxslt-1.1.10
works ok.

PPS:
if I return string from function - it works:

// convert IPv4 address (string) to number
static void xslIp2Number(xmlXPathParserContextPtr ctxt, int nargs)
{
  xsltTransformContextPtr tctxt = getContext(ctxt);
  if (!tctxt) return;

  xmlChar *xstr = xmlXPathPopString(ctxt);

  struct in_addr ad;
  if(inet_aton((char *)xstr, &ad) == 1) {
        unsigned long num = (unsigned long)ntohl(ad.s_addr);
        char buf[32];
        snprintf(buf, 31, "%lu", num);

        valuePush(ctxt, xmlXPathNewString(BAD_CAST buf));
  } else
        valuePush(ctxt, xmlXPathNewNodeSet(NULL));

  xmlFree(xstr);
}


What wrong with numbers ?

-- 
Vladimir B. Grebenchikov
vova fbsd ru


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