Re: [xsl] Problem in define Node-set from variable number of params

Subject: Re: [xsl] Problem in define Node-set from variable number of params
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Thu, 29 Mar 2001 10:00:28 +0100
Hi Yang,

> But when I use the variable of "condition2" generated from various params
> test, it fails.

OK. The bit problem here is that you're trying to set the value of the
xsl:variable's 'select' attribute by creating an attribute with
xsl:attribute.

> <xsl:variable name="condition2">
>   <xsl:attribute name="select">
>     <xsl:choose>
>       <xsl:when test="string($office) and string($month)">
>          key('prodCode',$thisPP)[substring(@SalesOrderNo,1,4)=$office
> ][substring(@SalesOrderNo,10,2)=$month]
>       </xsl:when>
>       <xsl:when test="string($office)">
>          key('prodCode',$thisPP)[substring(@SalesOrderNo,1,4)= $office]
>       </xsl:when>
>       <xsl:when test="string($month)">
>          key('prodCode',$thisPP)[substring(@SalesOrderNo,10,2)=$month]
>       </xsl:when>
>       <xsl:otherwise>key('prodCode',$thisPP)</xsl:otherwise>
>     </xsl:choose>
>   </xsl:attribute>
> </xsl:variable>

xsl:attribute is used to create attributes *on the result tree* - on
the output that you're creating. You cannot use it to set attributes
on the XSLT instructions in your stylesheet.

You can set variables either through the select attribute or through
their content. When an XSLT processor sees the above, it thinks you're
trying to set the value of the variable through its content. Setting a
variable through its content gives a result tree fragment, which is
like a mini document, with its own root node and whatever you specify
inside the document being children of that root node.

A conforming processor should then object because you're trying to
create an attribute on the root node, and root nodes can't have
attributes.

So, how do you create the conditional node set that you want?  Well,
one thing about predicates is that you can put any test you want
within them.  So for example, the following only filters the
key('prodCode', $thisPP) nodes by month if a month is set (the third
condition in your test above):

  key('prodCode', $thisPP)
    [not(string($month)) or substring(@SalesOrderNo, 10, 2) = $month]

So in fact you can link all your conditions together. You want to
produce the result of key('prodCode' $thisPP) if neither $month nor
$office are specified. If $month or $office is specified, you only
want those nodes with the relevant @SalesOrderNo.  I think that this
translates to:

  key('prodCode', $thisPP)
    [not(string($office)) or substring(@SalesOrderNo, 1, 4) = $office]
    [not(string($month)) or substring(@SalesOrderNo, 10, 2) = $month]

(I'm just using two predicates for clarity here - you could join them
together with an 'and' if you wanted.)

Since this is a single XPath expression, you can put it in the select
attribute of the xsl:variable:

  <xsl:variable name="condition2"
     select="key('prodCode', $thisPP)
                [not(string($office)) or
                 substring(@SalesOrderNo, 1, 4) = $office]
                [not(string($month)) or
                 substring(@SalesOrderNo, 10, 2) = $month]

I hope that helps,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/



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


Current Thread