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

Subject: Re: [xsl] max string-length for context grandchildren
From: Eliot Kimber <ekimber@xxxxxxxxxxxx>
Date: Tue, 4 Oct 2011 21:29:41 -0500
<xsl:variable name="maxlen"
  select=" max(for $str in distinct-values(./*/label) return
string-length($str))"
/>

Gives me the result "14" on your test data.

This will work in XSLT 2, not 1.

Cheers,

E.

On 10/4/11 9:08 PM, "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.  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).  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.
> 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>
>     <list type="deflist">
>         <head>This is a test list</head>
>         <defitem>
>             <label>Processed by</label>
>             <item>Lynette Stoudt</item></defitem>
>         <defitem>
>             <label>Date Completed</label>
>             <item>February 1999</item></defitem>
>         <defitem>
>             <label>Encoded by</label>
>             <item>William Landis</item>
>         </defitem>
>     </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].
> The calculation needs to be made while <list> is the context node.  I've
tried
> two different approaches:
>
> 1) It seems to me that it should be possible to do something like this:
>
>     <xsl:template match="list">
>         <template match="list">
>             <xsl:variable name="longest-label"
> select="max(string-length(deflist/label))"/>
>             <xsl:value-of select="$longest-label"/>
>         </template>
>     </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."
>
>     <xsl:template match="list">
>         <xsl:variable name="longest-label">
>             <xsl:call-template name="getlongest">
>                 <xsl:with-param name="nodeset" select="defitem/label"/>
>                 <xsl:with-param name="longest"/>
>             </xsl:call-template>
>         </xsl:variable>
>         <xsl:text>LongestLabel </xsl:text><xsl:value-of
> select="$longest-label"></xsl:value-of>
>     </xsl:template>
>
>     <xsl:template name="getlongest">
>         <xsl:param name="nodeset"/>
>         <xsl:param name="longest" select="0"/>
>         <xsl:choose>
>             <xsl:when test="$nodeset">
>                 <xsl:choose>
>                     <xsl:when test="string-length($nodeset[1]) > $longest">
>                         <xsl:call-template name="getlongest">
>                             <xsl:with-param name="nodeset"
> select="$nodeset[position()  > 1]"/>
>                             <xsl:with-param name="longest"
> select="string-length($nodeset[1])"/>
>                         </xsl:call-template>
>                     </xsl:when>
>                     <xsl:otherwise>
>                         <xsl:call-template name="getlongest">
>                             <xsl:with-param name="nodeset"
> select="$nodeset[position()  > 1]"/>
>                             <xsl:with-param name="longest"
select="$longest"/>
>                         </xsl:call-template>
>                     </xsl:otherwise>
>                 </xsl:choose>
>             </xsl:when>
>             <xsl:otherwise>
>                 <xsl:value-of select="$longest"/>
>             </xsl:otherwise>
>         </xsl:choose>
>     </xsl:template>
>
> I can't actually find the "<" that is at issue here.  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
>

--
Eliot Kimber
Senior Solutions Architect
"Bringing Strategy, Content, and Technology Together"
Main: 512.554.9368
www.reallysi.com
www.rsuitecms.com

Current Thread