Snow
Snow

Reputation: 49

XSLT: Using position() in select path

I'm trying to use position to control a select, but it only seems to work when using literal ints. I've created a very cut down example that skips a lot of other context, so while it may seem like I'm doing this inefficiently, there are good reasons for it.

Input:

<container xmlns:xlink="http://www.w3.org/1999/xlink">
<item type="a" xlink:href="a1.xxx"/>
<item type="b" xlink:href="b1.jpg"/>
<item type="c" xlink:href="c1.jpg"/>
<item type="a" xlink:href="a2.xxx"/>
<item type="b" xlink:href="b2.jpg"/>
<item type="c" xlink:href="c2.jpg"/>
<assocData type="typeOne" xlink:href="objectOne"/>
<assocData type="typeTwo" xlink:href="objectThree"/>
<assocData type="typeOne" xlink:href="objectTwo"/>
<assocData type="typeTwo" xlink:href="objectFour"/>
</container>

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">

    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:template match="container">
        <xsl:for-each select="item[@type='b']">
            <container>
                <xsl:variable name="position">
                    <xsl:value-of select="position()"/>
                </xsl:variable>
                <xsl:copy-of select="../assocData[@type='typeOne'][$position]"/>
            </container>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

Desired output:

<container>
<assocData type="typeOne" xlink:href="objectOne"/>
</container>
<container>
<assocData type="typeOne" xlink:href="objectTwo"/>
</container>

Actual output:

<container>
<assocData type="typeOne" xlink:href="objectOne"/>
<assocData type="typeOne" xlink:href="objectTwo"/>
</container>
<container>
<assocData type="typeOne" xlink:href="objectOne"/>
<assocData type="typeOne" xlink:href="objectTwo"/>
</container>

If I replace '$position' with a literal 1 or 2, each container in the output contains only one assocData tag. I'm not sure why it's behaving differently for the variable containing the position.

Upvotes: 1

Views: 1676

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167581

Change

 <xsl:variable name="position">
                    <xsl:value-of select="position()"/>
                </xsl:variable>

to

 <xsl:variable name="position" select="position()"/>

as in that case the variable is of type integer while in your case it is a result tree fragment containing a text node which happens to be a numeric value.

Upvotes: 2

Related Questions