Re: [xsl] max string-length for context grandchildren

Subject: Re: [xsl] max string-length for context grandchildren
From: Mukul Gandhi <gandhi.mukul@xxxxxxxxx>
Date: Wed, 5 Oct 2011 09:05:23 +0530
Hi Eric,
   Given your input XML document, the following 2.0 stylesheet gives
me the needed result,

<xsl:template match="/">
    <xsl:value-of select="max(/record/list/defitem/label/string-length())"/>
</xsl:template>


On Wed, Oct 5, 2011 at 7:38 AM, Eric Harbeson
<kiteeatingtree@xxxxxxxxxxxxx> wrote:
> Dear all,
>
> I am trying to determine the length of the longest string of a given
element, which is the grand-child of the context node. B I've looked all over
the archives and haven't found anything that I can get to work (possibly an
indictment of my searching skills). B So I'm hoping a kind soul will take pity
and help me.
>
> Details first: I'm using XSLT 2.0, though a 1.0 solution would be fine too.
B I've tried processing using Saxon [PE | HE | EE] 9.3.0.5, as contained in
oXygen 12.2.
>
>
> I have the following XML:
>
> <record>
> B  B <list type="deflist">
> B  B  B  B <head>This is a test list</head>
> B  B  B  B <defitem>
> B  B  B  B  B  B <label>Processed by</label>
> B  B  B  B  B  B <item>Lynette Stoudt</item></defitem>
> B  B  B  B <defitem>
> B  B  B  B  B  B <label>Date Completed</label>
> B  B  B  B  B  B <item>February 1999</item></defitem>
> B  B  B  B <defitem>
> B  B  B  B  B  B <label>Encoded by</label>
> B  B  B  B  B  B <item>William Landis</item>
> B  B  B  B </defitem>
> B  B </list>
> </record>
>
> I'm trying to determine which of the three <label> elements is the longest,
so my desired output is: 14, which is the string length of
list/defitem/label[2]. B The calculation needs to be made while <list> is the
context node. B I've tried two different approaches:
>
> 1) It seems to me that it should be possible to do something like this:
>
> B  B <xsl:template match="list">
> B  B  B  B <template match="list">
> B  B  B  B  B  B <xsl:variable name="longest-label"
select="max(string-length(deflist/label))"/>
> B  B  B  B  B  B <xsl:value-of select="$longest-label"/>
> B  B  B  B </template>
> B  B </xsl:template>
>
> ...but this returns the number zero.
>
> 2) The closest thing I've found to an answer is the dual parameter solution
recommended by Michael Kay and as implemented by Phil Lanch on the dpawson FAQ
site (http://www.dpawson.co.uk/xsl/sect2/N8090.html#d10874e649 (#16: How to
find the longest node in a node-set)).
>
> My implementation of that (which follows) generates the following error,
which I can't explain: "Required item type of first operand of '<' is numeric;
supplied value has item type xs:string."
>
> B  B <xsl:template match="list">
> B  B  B  B <xsl:variable name="longest-label">
> B  B  B  B  B  B <xsl:call-template name="getlongest">
> B  B  B  B  B  B  B  B <xsl:with-param name="nodeset"
select="defitem/label"/>
> B  B  B  B  B  B  B  B <xsl:with-param name="longest"/>
> B  B  B  B  B  B </xsl:call-template>
> B  B  B  B </xsl:variable>
> B  B  B  B <xsl:text>LongestLabel </xsl:text><xsl:value-of
select="$longest-label"></xsl:value-of>
> B  B </xsl:template>
>
> B  B <xsl:template name="getlongest">
> B  B  B  B <xsl:param name="nodeset"/>
> B  B  B  B <xsl:param name="longest" select="0"/>
> B  B  B  B <xsl:choose>
> B  B  B  B  B  B <xsl:when test="$nodeset">
> B  B  B  B  B  B  B  B <xsl:choose>
> B  B  B  B  B  B  B  B  B  B <xsl:when test="string-length($nodeset[1]) >
$longest">
> B  B  B  B  B  B  B  B  B  B  B  B <xsl:call-template name="getlongest">
> B  B  B  B  B  B  B  B  B  B  B  B  B  B <xsl:with-param name="nodeset"
B select="$nodeset[position() B > 1]"/>
> B  B  B  B  B  B  B  B  B  B  B  B  B  B <xsl:with-param name="longest"
select="string-length($nodeset[1])"/>
> B  B  B  B  B  B  B  B  B  B  B  B </xsl:call-template>
> B  B  B  B  B  B  B  B  B  B </xsl:when>
> B  B  B  B  B  B  B  B  B  B <xsl:otherwise>
> B  B  B  B  B  B  B  B  B  B  B  B <xsl:call-template name="getlongest">
> B  B  B  B  B  B  B  B  B  B  B  B  B  B <xsl:with-param name="nodeset"
B select="$nodeset[position() B > 1]"/>
> B  B  B  B  B  B  B  B  B  B  B  B  B  B <xsl:with-param name="longest"
select="$longest"/>
> B  B  B  B  B  B  B  B  B  B  B  B </xsl:call-template>
> B  B  B  B  B  B  B  B  B  B </xsl:otherwise>
> B  B  B  B  B  B  B  B </xsl:choose>
> B  B  B  B  B  B </xsl:when>
> B  B  B  B  B  B <xsl:otherwise>
> B  B  B  B  B  B  B  B <xsl:value-of select="$longest"/>
> B  B  B  B  B  B </xsl:otherwise>
> B  B  B  B </xsl:choose>
> B  B </xsl:template>
>
> I can't actually find the "<" that is at issue here. B When debugging, I
noted that the value of $nodeset is never a number, but some thing like
"<label><label><label>", though I can't see why.
>
> Any thoughts would be very appreciated.
>
> With thanks in advance,
> Eric Harbeson





--
Regards,
Mukul Gandhi

Current Thread