This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Strange Parameter Behavior


Thanks to all who responded.  Tripped up yet again by the wily nuances of 
XPath :)  There were two things at work here:

1. For some reason, I figured if I specified the first matching c element, 
it would select only one node:

    <xsl:param name="param-id" select="/a/b/c[1]/@id"/>

But in fact it returns a node-set with the first c in every b of every a.

2. Which explains the results:

    param-id: 3
    prev: 6
    next: 4

Since $param-id actually refers to a node-set, the equality operator behaves 
a little differently.  In this case, the $param-id node-set contains:

    <c id="3"/>
    <c id="8"/>
    <c id="12"/>

As such, the first part of the XPath in question matches a node-set as well, 
containing the above 3 nodes:

    //c[@id = $param-id]

But since the first c has no preceding c, the entire XPath matches only the 
2 nodes with preceding c's:

    //c[@id = $param-id]/preceding::c[1]/@id

    <c id="6"/>
    <c id="10"/>

So the value-of must implicitly return just the first of these 2 matches, 
which is

    <c id="6"/>

The correct solution in my case is either of:

    <xsl:param name="param-id" select="(/a/b/c)[1]/@id"/>
    <xsl:param name="param-id" select="/a[1]/b[1]/c[1]/@id"/>

As suggested by a couple of you.  Again, thanks.

I hope I'm close; something just clicked and I hope it wasn't my hip :)

Mike

>From: "Michael Peet" <mjpeet@hotmail.com>
>Reply-To: xsl-list@lists.mulberrytech.com
>To: xsl-list@lists.mulberrytech.com
>Subject: [xsl] Strange Parameter Behavior
>Date: Thu, 09 May 2002 17:01:41 -0400
>
>Given the XML:
>
><a id="1">
>  <b id="2">
>    <c id="3"/>
>    <c id="4"/>
>    <c id="5"/>
>    <c id="6"/>
>  </b>
>  <b id="7">
>    <c id="8"/>
>    <c id="9"/>
>    <c id="10"/>
>  </b>
>  <b id="11">
>    <c id="12"/>
>    <c id="13"/>
>    <c id="14"/>
>  </b>
></a>
>
>
>And XSLT of:
>
><xsl:stylesheet version="1.0"
>xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
>
>  <xsl:output encoding="ascii" omit-xml-declaration="yes" indent="yes"/>
>  <xsl:strip-space elements="*"/>
>
>  <xsl:param name="param-id" select="/a/b/c[1]/@id"/>
>
>  <xsl:template match="/">
>    param-id: <xsl:value-of select="$param-id"/><br/>
>    prev: <xsl:value-of select="//c[@id =
>$param-id]/preceding::c[1]/@id"/><br/>
>    next: <xsl:value-of select="//c[@id =
>$param-id]/following::c[1]/@id"/><br/>
>  </xsl:template>
>
></xsl:stylesheet>
>
>
>I get the following expected results when passing in a parameter:
>
>param-id: 12
>prev: 10
>next: 13
>
>
>However, when I don't pass anything in and let the default parameter take
>over, I get this output:
>
>param-id: 3
>prev: 6
>next: 4
>
>
>Could anyone explain this?  Is there a RTF at work here?  When I wrap the
>default parameter value with a string() function, the stylesheet returns 
>the
>expected results:
>
>param-id: 3
>prev:
>next: 4
>
>
>Is that the "correct" solution?  More importantly, does anyone know why 
>case
>2 produces those results?  It evaluates 'next' correctly, but why is 'prev'
>so far off?
>
>Thanks in advance!
>
>Mike
>
>
>
>_________________________________________________________________
>Join the world’s largest e-mail service with MSN Hotmail.
>http://www.hotmail.com
>
>
>XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
>


_________________________________________________________________
Send and receive Hotmail on your mobile device: http://mobile.msn.com


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]