views:

89

answers:

1

Consider the following XSLT 2.0 template

<xsl:template match="/">
    <xsl:variable name="var1">
        <elem>1</elem>
        <elem>2</elem>
        <elem>3</elem>
    </xsl:variable>
    <xsl:text>var1 has </xsl:text>
    <xsl:value-of select="count($var1)"/>
    <xsl:text>elements.
    </xsl:text>

    <xsl:variable name="var2" select="$var1/elem[position() &gt; 1]"/>
    <xsl:text>var2 has </xsl:text>
    <xsl:value-of select="count($var2)"/>
    <xsl:text>elements.
    </xsl:text>
</xsl:template>

The output of this template is

var1 has 1 elements
var2 has 2 elements

The first line outputs 1 (and not, as I first expected 3) because var1 is a document fragment that contains the <elem> elements as childen. Now for my questions:

How can I create a variable that does not contain a document fragment? I could do it like I did with var2, only leaving out the predicate. But maybe there is a way without using a second variable. Or, as an alternative: How can I preserve the document fragment in a variable while filtering out some elements?

Background Information: I will be using the variable contents in a recursive function that checks the first element in var1 for certain criteria. If the criteria are met or the list of elements is empty, it returns a value. Otherwise it will call itself with the first element of var1 removed (like I do in var2). When using var1 as a parameter that contains a document fragment, the XPath expressions in my template will not match.

+1  A: 

How can I create a variable that does not contain a document fragment?

Use:

<xsl:variable name="var1" as="element()*"> 
    <elem>1</elem> 
    <elem>2</elem> 
    <elem>3</elem> 
</xsl:variable> 

How can I preserve the document fragment in a variable while filtering out some elements?

If you have:

<xsl:variable name="var1"> 
    <elem>1</elem> 
    <elem>2</elem> 
    <elem>3</elem> 
</xsl:variable> 

Use:

  <xsl:variable name="var2">
    <xsl:copy-of select="$var1/*[. mod 2 = 1]"/>
  </xsl:variable> 
Dimitre Novatchev