Simon
Simon

Reputation: 7

XSLT How does following-sibling in template match work?

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

Answers (2)

Nic Gibson
Nic Gibson

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

Martin Honnen
Martin Honnen

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

Related Questions