Is there a way to avoid processing of already processed nodes?
Input XML
<?xml version="1.0" encoding="UTF-8"?>
<root>
<node1>node1.1</node1>
<node2>node2.1</node2>
<node2>node2.2</node2>
<node1>node1.2</node1>
</root>
XSL
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="root">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="node1">
[Node1]:<xsl:value-of select="."></xsl:value-of>
<xsl:apply-templates select="following-sibling::node2"/>
[End node1]
</xsl:template>
<xsl:template match="node2">
[Node2]:<xsl:value-of select="."></xsl:value-of>
</xsl:template>
</xsl:stylesheet>
Output
<?xml version="1.0" encoding="UTF-8"?>
[Node1]:node1.1
[Node2]:node2.1
[Node2]:node2.2
[End node1]
[Node2]:node2.1
[Node2]:node2.2
[Node1]:node1.2
[End node1]
As you can see template <xsl:template match="node2"> is applied twice for every node2 element – one time from node1 template and second time when XSLT processor is transforming node2 element.
Is there any solution to avoid applying of xsl:template match="node2" second time?
I need to stop processing of node2 when I just processed it in template for node1.
Important
This example is just an emulation of more complex use case.
This means that we have additonal limitation – we can’t modify template for root element processing.
I want to know if there is any way to stop processing of elements or move processing to some other elements.
You can use
modeto name the template to use.You can create an empty catch-all node that will output nothing, taking care of
apply-templatescalls that have noselect.The following stylesheet outputs what you need:
Note the empty modeless template at the end, and the added
modeattribute on the template and the callingapply-templates.