xmlxsltxpathvxml

Usage for xsl param in xpath


I defined a param array $gen as:

<xsl:variable name="inline-array">
    <item>western</item>
    <item>Romance</item>
    <item>Adventure</item>
    <item>Drama</item>
    <item>Comedy</item>
    <item>Horror</item>
    <item>Action</item>
</xsl:variable>
<xsl:param name="gen" select="document('')/*/xsl:variable[@name='inline-array']/*"/>

I want to transfer a XML to VXML by XSLT. Param $gen and $gen2 failed to select the value when I used it in Xpath

<xsl:value-of select>:
    <filled namelist="MovieSummary">
      <if cond="MovieSummary == '{$gen[1]}'">
        <prompt>
            <xsl:value-of select ="//genre[.='western']/../title"/>. <xsl:value-of select ="//genre[.='western']/../summary"/>
        </prompt>
    <xsl:for-each select="$gen[position()>1]">        
        <xsl:variable name="gen2"><xsl:value-of select="."/></xsl:variable>
        <elseif cond="MovieSummary == '{$gen2}'"/>
        <prompt>
            <xsl:value-of select ="//genre[.='$gen2']/../title"/>. <xsl:value-of select ="//genre[.='$gen2']/../summary"/>
        </prompt>   
    </xsl:for-each>
 <else/>
 </if> 
 </filled>

It failed to select the value when I use $gen2 instead of "Romance" or other string. But cond="MovieSummary == '{$gen[1]}'" works well. It can only generate something like:

  <if cond="MovieSummary == 'western'">`enter code here`
    <prompt>Range Feud. 
    Clint Turner is arrested for the murder of his girlfriend Judy's      
    father, a rival rancher who was an enemy of his own father.
    </prompt>
    <elseif cond="MovieSummary == 'Romance'"/>
    <prompt>. </prompt>
     <else/>
  </if>

I've tried:

select ="//genre[.=$gen2]/../summary"; 
select ="//genre[.={$gen2}]/../summary"; 
select ="//genre[.='{$gen2}']/../summary"

All failed.


Solution

  • The instruction:

    <xsl:for-each select="$gen[position()>1]">
    

    puts you in the context of $gen. From this context, the expression:

    <xsl:value-of select ="//genre[.='$gen2']/../title"/>
    

    selects nothing, because // starts from the root of the current document - but genre is in another document altogeher.

    You need to change the context back to the processed XML document in order to address the nodes within it.

    Note: in XSLT 2.0, the key() function can select nodes in another document directly, without changing the overall context.