XSL storage node-set in variable

(XSLT 1.0.) Given a variable called Rows, which contains the following (example):

Enter

<AllResults> <Result> <subject>can be filtered by filter 1</subject> <type>can be filtered by filter 2</type> <date>can be filtered by filter 3</date> </Result> <Result> ... </Result> </AllResults> 

I have 3 filter variables. For each filter, I would like to apply a filter to the input shown above if the filter variable is not empty. I would like to save the filtered result, the elements corresponding to the filters, in a new variable. I tried the following, but I got an error message (filterResult), which is a "result tree instead of node-set". The Rows variable is node-set, as I defined with the debugger.

XSL part

 <xsl:variable name="filterResult"> <xsl:choose> <xsl:when test="$filter1 != '' and $filter2 != '' and $filter3 != ''"> <xsl:copy-of select="$Rows[date=$filter1 and type=$filter2 and subject=$filter3]" /> </xsl:when> <xsl:when test="$filter1 != '' and $filter2 != ''"> <xsl:copy-of select="$Rows[date=$filter1 and type=$filter2]" /> </xsl:when> <xsl:when test="$filter1 != '' and $filter3 != ''"> <xsl:copy-of select="$Rows[date=$filter1 and subject=$filter3]" /> </xsl:when> <xsl:when test="$filter3 != '' and $filter2 != ''"> <xsl:copy-of select="$Rows[type=$filter2 and subject=$filter3]" /> </xsl:when> <xsl:when test="$filter1 != ''"> <xsl:copy-of select="$Rows[date=$filter1]" /> </xsl:when> <xsl:when test="$filter3 != ''"> <xsl:copy-of select="$Rows[subject=$filter3]" /> </xsl:when> <xsl:when test="$filter2 != ''"> <xsl:copy-of select="$Rows[type=$filter2]" /> </xsl:when> <xsl:otherwise> <xsl:copy-of select="$Rows" /> </xsl:otherwise> </xsl:choose> </xsl:variable> 

I understand that copy-of creates a result tree, not node-set, but I'm not sure HOW to create a node set, given my requirements for the 3 filters that I described above.

Additional Information

I know that I could do something like <xsl:variable name="me" select="/set/node"/> , which would create a variable containing the node set, but I don’t see how this helps me since I have many possible conditions (given the three filters).

+7
source share
2 answers

The $Rows variable $Rows be an instance of the Fragment type of the result tree.

You cannot perform any operation (for example, provided by the filter expression [] ) in RTF, except for operations with the string: from http://www.w3.org/TR/xslt#section-Result-Tree-Fragments

An operation is allowed by the result of a tree fragment only if this operation is allowed on a string (a string operation may include first converting the string to a number or a logical value). In particular, it is not permitted to use the / , // , and [] operators in the result tree fragments.

In addition, all of the code shown can be simplified if $Rows is an instance of a node of an installed data type as follows:

 <xsl:variable name="filterResult" select="$Rows[(date=$filter1 or $filter1='') and (type=$filter2 or $filter2='') and (subject=$filter3 or $filter3='')]"/> 

There is an XSLT processor (basically each) that provides an implementation of the node-set() extension function for RTF to node conversion setup.

+7
source

In XSLT 1.0, the only way to create a variable containing a collection of nodes from the source document is to evaluate the XPath expression in the select attribute:

 <xsl:variable name="name" select="xpath_expression"/> 

You cannot use copy-of , apply-templates or call-template ; all of them will generate a fragment of the result tree.

Every XSLT processor that I know about implements an extension function that converts fragments of the resulting tree to a node set, so if you don't need your conversion to be completely cross-platform, you can do something like this (in this example used by Microsoft XSLT):

 <xsl:variable name="filterResultNodeSet" select="msxsl:node-set($filterResult)"/> 

But you don’t have to do this: as Alejandro noted, you can get the result you are looking for by simply writing one XPath expression. There are applications in which node selection is so complex that you need to use the node-set() function, but yours is not one of them.

+11
source

All Articles