Re: [xsl] Evaluating an expression as an XPath expression

Subject: Re: [xsl] Evaluating an expression as an XPath expression
From: Trevor Nash <tcn@xxxxxxxxxxxxx>
Date: Fri, 21 Dec 2001 22:54:44 +0000
>A familiar problem: 
>
>What's the difference between:
>
>		<xsl:variable name="oexpr">//PO</xsl:variable>
>		<xsl:if test="saxon:eval(saxon:expression($oexpr))">
>			<p>Found it: <xsl:value-of select="$oexpr"/></p>
>		</xsl:if>
>
>and 
>
>		<xsl:for-each select="document(VC.xml')//Expr">
>			<xsl:variable name="expr"><xsl:value-of
>select="."/></xsl:variable> 
>			<xsl:if test="saxon:eval(saxon:expression($expr))">
>				<p>Found it: <xsl:value-of
>select="$expr"/></p>
>			</xsl:if>
>		</xsl:for-each>
>
>where VC.xml contains 
>
>	<Exprs>
>	<Expr>//PO</Expr>
>	</Exprs>
>
>?
>
>I can't seem to make the two tests come out the same (both positive when the
>XML file being processed has a PO element and both negative when it
>doesn't). The first seems to work; the second (with document()) fails.
>
>As usual, I suspect that I'm hitting the familiar node-set versus
>tree-fragment versus string-value-of-text-node thing.
>
>So my question is, what kind of thing is in $oexpr and which is in $expr?
>
Wrong question!!
$oexpr and $expr are identical (assuming you fix the typo in the
document() call, which is missing a single quote).

What is different is the context in which the expressions are
evaluated.  In the first case, the context node is from the main input
document, so //PO refers to an element in that document (or not).  In
the second case you are within a for-each which makes the context node
the Expr from the VC.xml document.  There is no PO element in that
document, so your test always fails regardless of what is in the main
document.

Try this:

<xsl:variable name="expr"
  select="string(document('VC.xml')//Expr)"/>

<xsl:if test="saxon:eval(saxon:expression($expr))">
  <p>Found it: <xsl:value-of select="$expr"/></p>
</xsl:if>

If you need to change the context for some other reason (e.g. you use
key() to retrieve the node from the subsidiary document) then you can
switch it back by using a global variable to hold the root and another
for-each.

Hope this helps,
Trevor Nash
--
Traditional training & distance learning,
Consultancy by email

Melvaig Software Engineering Limited
voice:     +44 (0) 1445 771 271 
email:     tcn@xxxxxxxxxxxxx

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


Current Thread