RE: Storing xpath expressions in a vaiable

Subject: RE: Storing xpath expressions in a vaiable
From: "Evan Lenz" <elenz@xxxxxxxxxxx>
Date: Thu, 28 Sep 2000 18:17:51 -0700
The XPath data types are as follows: string, number, node-set, boolean.
XSLT adds an additional data type called the result tree fragment (whose
days are numbered, as the next version of XSLT will likely do away with it).
There is no XPath data type that corresponds to an XPath expression.
Likewise, there is no eval() function that will let you evaluate a string as
an XPath expression.  I believe the rationale behind this was to enable
pre-compilation of XPath expressions as well as compile-time recognition of
ill-formed expressions.

The first thing to remember is that XSLT variables do not store XPath
expressions; instead, they always store one of the above five data types.
In your case, the strings you've included each correspond to an XPath
expression that would return a node-set.  Thus, ultimately, you'll want your
variable to contain a node-set, rather than a string.  You only need one
variable, rather than also an intermediate one containing an expression,
which is impossible (except as a dumb string).  But I see why you are
attempting this.  You need to conditionally determine which node-set to
select as the value of your variable.  The problem with this is that
conditional processing is done using XSLT element instructions.  As soon as
you begin talking about having elements as children of xsl:variable, you've
lost the chance to map the variable's value to a node-set, because an
xsl:variable that contains anything will always be an RTF, as you correctly
point out.  (But you don't want an RTF, even if it's converted to a
node-set, because it won't be converted to the node-set you're thinking of,
but to a node-set containing only one node, the root node of that tree,
instead of a node-set containing multiple NOTES elements).  Thus, you must
figure out a way to achieve the node-set you're looking for by using XPath
alone and no XSLT instructions.  I succeeded in doing this by adapting an
example from Mike Kay's book, page 551.  Try this:

Source:
<TABLE>
 <NOTES TEMPLATE="foo">1</NOTES>
 <NOTES TEMPLATE="bar">2</NOTES>
 <NOTES>3</NOTES>
 <NOTES>4</NOTES>
 <NOTES TEMPLATE="bar">5</NOTES>
 <NOTES TEMPLATE="foo">6</NOTES>
 <NOTES>7</NOTES>
</TABLE>


Stylesheet:
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

  <xsl:param name="filter_template"/>

  <xsl:variable name="filtered_notes" select="//TABLE/NOTES[$filter_template
and @TEMPLATE=$filter_template] | //TABLE/NOTES[not($filter_template)]"/>

  <xsl:template match="/">
    <xsl:for-each select="$filtered_notes">
      <xsl:copy-of select="."/>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>


The XPath expression contains the union of both node-sets, one of which will
always be empty, depending on whether filter_template was assigned or not,
and the other of which will contain either all the NOTES elements or only
those that have a certain TEMPLATE attribute value.

Here are the results after assigning no value, "foo", and "bar",
respectively.

C:\>saxon test.xml test.xsl
<?xml version="1.0" encoding="utf-8" ?><NOTES TEMPLATE="foo">1</NOTES><NOTES
TEM
PLATE="bar">2</NOTES><NOTES>3</NOTES><NOTES>4</NOTES><NOTES
TEMPLATE="bar">5</NO
TES><NOTES TEMPLATE="foo">6</NOTES><NOTES>7</NOTES>

C:\>saxon test.xml test.xsl filter_template=foo
<?xml version="1.0" encoding="utf-8" ?><NOTES TEMPLATE="foo">1</NOTES><NOTES
TEM
PLATE="foo">6</NOTES>

C:\>saxon test.xml test.xsl filter_template=bar
<?xml version="1.0" encoding="utf-8" ?><NOTES TEMPLATE="bar">2</NOTES><NOTES
TEM
PLATE="bar">5</NOTES>


It seems rather limited, but in this case it works!  Enjoy.

Evan Lenz
elenz@xxxxxxxxxxx
http://www.xyzfind.com
XYZFind, the search engine *designed* for XML
Download our free beta software: http://www.xyzfind.com/beta



-----Original Message-----
From: owner-xsl-list@xxxxxxxxxxxxxxxx
[mailto:owner-xsl-list@xxxxxxxxxxxxxxxx]On Behalf Of
Sridhar_Ramachandran@xxxxxx
Sent: Thursday, September 28, 2000 2:43 PM
To: xsl-list@xxxxxxxxxxxxxxxx
Subject: Storing xpath expressions in a vaiable



Hi,
     I am trying to store an xpath expression in variable and trying to
evaluate it and storing the results in another variable. The xpath
expression used might depend on the value of some parameter(s) passed to
the style sheet. I am storing the xapth expression as follows :

     <xsl:variable name="note_filter_expression">
        <xsl:choose>
            <xsl:when test="$filter_template">
                <xsl:value-of select = "'//TABLE/NOTES[@TEMPLATE
=$filter_template]'"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="'//TABLE/NOTES'"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>

In the above xsl code fragment, "filter_template" is a parameter passed to
the stylesheet. I would the like to evaluate the xpath expression stored in
$note_filter_expression and store the list of NOTES nodes returned in a
variable.  I need a node-list instead of RTREEFRAG, for later processing. I
am using XALAN and it does not seem to provide a node-list() funtion like
xt/saxon. I tried

 <xsl:variable name = "filtered_notes" select ='$note_filter_expression'/>

but this simply puts thestring representing the xpath expression into
$filtered_notes.

Any help is appreciated.

rgds

Sridhar


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


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


Current Thread