user3198443
user3198443

Reputation: 95

XSLT 2. 0 select node specific with variable vs direct select

I'm trying to process each rule in a table cell, and I'm having a problem accessing the correct attribute values when I'm using a variable.

I'm trying to only process the bottom rules (@flags="b"). Given this xml

<?xml version="1.0" encoding="UTF-8"?>
<cell>
    <rules>
        <rule flags="t" width="0.3528" colour="black"/>
        <rule flags="b" width="0.3528" colour="black"/>
        <rule flags="b" width="0.7056" colour="none"/>
        <rule flags="b" width="0.3528" colour="black"/>
    </rules>
<para>19.3%</para>
</cell>

If I use this xslt

 <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
   <xsl:template match="cell">
     <xsl:variable name="i">2</xsl:variable>
     <xsl:value-of select="child::rules/rule[contains(@flags, 'b')][2]/@width"/>
   </xsl:template>
</xsl:stylesheet>

The result is '0.7056', which is what I am looking for, but if I use a variable in my select

     <xsl:value-of select="child::rules/rule[contains(@flags, 'b')][$i]/@width"/>

The result is '0.3528 0.7056 0.3528'. It's grabbing the width attribute of all of my rules elements, not just the second one, even though the variable does have a value of 2.

I'm wondering why using a variable versus a specific number would make a difference, and how I might go about fixing this.

Upvotes: 2

Views: 264

Answers (2)

Daniel Haley
Daniel Haley

Reputation: 52878

When you create your variable by putting the "2" inside of it like this:

<xsl:variable name="i">2</xsl:variable>

you create a result tree fragment.

If you create it like this:

<xsl:variable name="i" select="2"/>

it's an actual number and can be used like you used it in the predicate.

A few notes about your xsl:value-of...

  • Depending on your data, using contains() to test the flags attribute might not be very accurate. If flags can have more than one value, consider using tokenize().
  • Although using the child:: axis is ok, it's not absolutely necessary.

Example:

<xsl:value-of select="rules/rule[tokenize(@flags,'\s+')='b'][$i]/@width"/>

Upvotes: 2

Rupesh_Kr
Rupesh_Kr

Reputation: 3435

for variable you have to use

<xsl:value-of select="child::rules/rule[contains(@flags, 'b')][position() = $i]/@width"/>

Upvotes: 0

Related Questions