Reputation: 7
I have a basic question about understanding preceding/following-sibling in templates.
I have the following XML Source:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<a>A</a>
<b>B</b>
<c>C</c>
<d>D</d>
<e>E</e>
<more>FGHIJ</more>
</root>
I want to copy everything except the nodes on the same level after <c>
. This shoud be done in a generic way.
So I wrote this XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[following-sibling::c]">
<xsl:copy>
<xsl:text>modified</xsl:text>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Coud someone please explain why <xsl:template match="*[following-sibling::c]">
in this case matches everything before <c>
and how to do this the right way? As I expected it to match everything after <c>
and do not understand why.
Thanks a lot!
Upvotes: 0
Views: 979
Reputation: 7143
Your match statement *[following-sibling::c]
matches every element which has an <c>
element that comes after it in document order (where those elements share a parent element). However, your identity transform will still include the ones that follow <c>
Given that, try removing your second template and adding the following:
<xsl:template match="*[preceding-sibling::c]"/>
That will suppress these elements after <c>
. It's often easier to suppress the elements you don't want in this sort of case than it is to try to include the other elements.
Upvotes: 2
Reputation: 167716
match="*"
matches any element and match="*[following-sibling::c]"
matches any element for which the condition in the predicate in square brackets holds, namely any element which has a following sibling which is a c
element.
Upvotes: 0