JBaruch
JBaruch

Reputation: 22893

XSLT - replace reoccuring parts of XML document (at any level)

pros, I need to convert the 'B' tag with 'X' tag in the following document:

<a>
 <B marker="true">
  <c>
    <B marker="true">
      <d>
        <B marker="true">
        </B>
       <d>
    </B>
  </c>
 </B>
</a>

Note the reoccurring 'B', it can appear at any depth in dynamic XML. Here's what I did:

<xsl:template match="//*[@marker='true']">
    <X>
        <xsl:copy-of select="./node()"/>
    </X>
</xsl:template>

It worked for the top-most 'B' tag, but ignored all the nested ones.

I think I know what the problem is - 'copy-of' just flushes the content of the top-most 'B' tag, without evaluating it. What can I do to make 'copy-of' reevaluate my template?

Thanks! Baruch.

Upvotes: 1

Views: 270

Answers (1)

Flack
Flack

Reputation: 5892

I would go with identity transform.

This code:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="B[@marker = 'true']">
        <X>
            <xsl:apply-templates/>
        </X>
    </xsl:template>
</xsl:stylesheet>

Against this XML input:

<a>
    <B marker="true">
        <c test="test">
            testText
            <B marker="true">
                <d>
                    testText2
                    <B marker="true">
                        testText3
                    </B>
                </d>
            </B>
            testText4
        </c>
        testText5
    </B>
</a>

Will provide this correct result:

<a>
    <X>
        <c test="test">
            testText
            <X>
                <d>
                    testText2
                    <X>
                        testText3
                    </X>
                </d></X>
            testText4
        </c>
        testText5
    </X>
</a>

Upvotes: 7

Related Questions