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]

Re: Putting parameter into XPATH expression


James:

At 08:23 PM 6/22/01, you wrote:
>Hi,
>
>In the code extract below, I always get the result "OneOneOne" instead of
>"OneTwoThree" which I am expecting.
>
>I found a work around (based on my previous experience writing compilers)
>that gets XSL processor to do what I want: "<xsl:value-of
>select="a/b[$Position + 0 ]/c"/>"

Your code is working this way because you are sending strings into your 
named templates as parameters, not numbers. So the expression

<xsl:value-of select="a/b[$Position ]/c"/>

is returning a set of nodes including *all* <c> elements (since a non-empty 
string tests as true, b[$Position] gets you every <b> element in that 
step). The value of a set of nodes is the value of the first node in the 
set, hence OneOneOne.

<xsl:value-of  select="a/b[$Position + 0 ]/c"/>

is working the way you want because adding a number (0) to a string 
($Position), the processor casts the string to a number as if by the 
number() function, effectively changing the predicated expression into a 
number.

Far easier would be simply to pass numbers in as parameters, not strings, 
which you could do by saying

<xsl:with-param name="Position" select="1"/>

instead of <xsl:with-param name="Position" select="'1'"/> (which you have now).

But why not just write a stylesheet that traverses the tree in the normal 
way? In fact, in your case the null stylesheet

<xsl:stylesheet version="1.0"
                 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"/>

would get you the output OneTwoThree, since the built-in default templates 
process the tree recursively, copying text nodes to output. (Well, actually 
it won't, because of the whitespace floating around your source document, 
which the processor will also faithfully copy; but it would if you stripped 
whitespace nodes with an <xsl:strip-space elements="*"/> statement. Try it, 
you'll see what I mean.)

Confused? It's all because of XSLT's powerful and really-not-so-mysterious 
processing model (that you do have to learn if you want to know how to make 
things work easily). Want to prevent those text nodes (or any other nodes 
that might happen to be around) from getting in the way? the stylesheet

<xsl:stylesheet version="1.0"
                 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

<xsl:template match="/">
   <xsl:for-each select="//c">
      <xsl:apply-templates/>
   </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

will get you the output you want.

But maybe you want to jump around arbitrarily, controlling the flow order 
by some logic in the stylesheet, not the source document? Then maybe you 
need something like what you're writing. If you simply want output that 
reflects the content of the input in its native order, XSLT is designed to 
do that anyway with minimal fuss.

Regards,
Wendell

>Can someone tell me a better (more correct) way to do this?
>
>XML ------------------
><?xml version="1.0" encoding="ISO-8859-1"?>
><a>
>   <b>   <c>One</c> </b>
>   <b>   <c>Two</c> </b>
>   <b>   <c>Three</c> </b>
></a>
>
>
>In my XSL, I do the following to write out the words One, Two and Three
>---------------
>
><?xml version="1.0" encoding="UTF-8"?>
><xsl:stylesheet version="1.0"
>xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
>
><xsl:output method="text"/>
>
><xsl:template match="/">
>                                 <xsl:call-template name="Jump">
>                                     <xsl:with-param name="Position"
>select="'1'"/>
>                                 </xsl:call-template>
>
>                                 <xsl:call-template name="Jump">
>                                     <xsl:with-param name="Position"
>select="'2'"/>
>                                 </xsl:call-template>
>
>                                 <xsl:call-template name="Jump">
>                                     <xsl:with-param name="Position"
>select="'3'"/>
>                                 </xsl:call-template>
></xsl:template>
>
><xsl:template name="Jump">
>                 <xsl:param name="Position"/>
>
>         <xsl:value-of select="a/b[$Position ]/c"/>
>
></xsl:template>


======================================================================
Wendell Piez                            mailto:wapiez@mulberrytech.com
Mulberry Technologies, Inc.                http://www.mulberrytech.com
17 West Jefferson Street                    Direct Phone: 301/315-9635
Suite 207                                          Phone: 301/315-9631
Rockville, MD  20850                                 Fax: 301/315-8285
----------------------------------------------------------------------
   Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================


 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]