Making XSLT ignore a node in the source

Here should go questions about transforming XML with XSLT and FOP.
GraemeBryce
Posts: 12
Joined: Tue Mar 21, 2006 12:06 pm

Making XSLT ignore a node in the source

Post by GraemeBryce »

does anyone have a way to create a template in XSLT that in effect removes a node (but not its children) from the input document and then continues to process as if it had never been there.

By example I have the following XML

Code: Select all


<root>
<columns>
<column id="aaa" />
<column id="bbb" />
<ignoreme>
<column id="ccc" />
<column id="ddd" />
</ignoreme>
<differentstuff>
<column id="111" />
<column id="222" />
<column id="333" />
</differentstuff>
<column id="eee" />
</columns>
</root>
My XSL MUST contain a match="columns/column" and can not contain a match simply for "column" as this will find many other nodes that are not relevant.

My aim is to output the nodes with ids "aaa" to "eee" but not to output "111" to "333"

I appreciate I could change the match to include columns/column AND columns/ignoreme/column but that is not practical in the real process.

So what I am looking for is a way to ADD something to the existing stylesheets that in effect causes the remaining stylesheet to act as if the <ignoreme> nodes had never existed and that the child <column> nodes were the immediate children of <columns>

Is there something that can be done with <xsl:copy-of/> that places the child nodes in the output tree but then processes it again?

I am not a newbie and can assure you that if it were possible to alter the existing styles to xpath matches that ignored the nodes then I would - if only!

Many thanks for any assistance

Graeme
george
Site Admin
Posts: 2095
Joined: Thu Jan 09, 2003 2:58 pm

Post by george »

Hi Graeme,

The simplest approach is to perform the transformation with two stylesheets, the first one filters out the elements that you want to be removed and the second does the actual processing on the expected input document.
You can perform the transformation inside a single stylesheet but for XSLT 1.0 you will need the node-set extension. For instance you can have templates in two modes, one does the filtering ather the actual processing. Then your main template can look like this

* declare a variable having as value the result of applying the templates with the mode filter
* declare another variable that gets the node-set value of the first variable (the first variable will be a result tree fragment in XSLT 1.0)
* apply the templates in the processing mode on the second variable

Best Regards,
George
GraemeBryce
Posts: 12
Joined: Tue Mar 21, 2006 12:06 pm

apply-templates on a variable in XSLT 1.0

Post by GraemeBryce »

George

I do not have the option of running two separate transforms per your option 1.

I can however follow your option 2 and indeed had already created a set of mode templates that do resolve the required tree into a variable. I ran into a problem with this in that if you try and do an <apply-templates /> on a variable you get the error "Expression must evaluate to a node-set"

It is clear that in your reply you have dealt with this in the step
* declare another variable that gets the node-set value of the first variable (the first variable will be a result tree fragment in XSLT 1.0)
However I must confess that I do not understand how to achieve this. Can you please elaborate on how to return a node-set value from a result-tree-fragment.

Many thanks in advance as it appears the solution you propose does deal with my problem.

Graeme
george
Site Admin
Posts: 2095
Joined: Thu Jan 09, 2003 2:58 pm

Post by george »

The node-set funtion is processor dependent, however the following should work with most XSLT processors:

Code: Select all


    <xsl:variable name="test">
<a>
test
</a>
</xsl:variable>
<xsl:variable xmlns:exslt="http://exslt.org/common" name="testNodeSet" select="exslt:node-set($test)"/>
<xsl:apply-templates select="$testNodeSet/*"/>
See also
http://www.exslt.org/exsl/functions/node-set/

Best Regards,
George
GraemeBryce
Posts: 12
Joined: Tue Mar 21, 2006 12:06 pm

Post by GraemeBryce »

George

Many thanks, this does provide a solution and is working perfectly.

Graeme
Post Reply