0
votes

I am trying to transform an XML using XSLT but need to avoid the elements inside a particular node from being transformed. How can I achieve that?

My current XSLT modifies all the nodes. Below is my XML and I need to avoid all the elements in <Makers> node from being transformed:

<Data>
       <Makers>
            <Type>ABC</Type>
            </Set>
            <Block>
                <FirstName>ZSPZCVCR</FirstName>
                <LastName/>
            </Block>
        </Makers>
        <Keeper>
            <Code>12</Node>
            <Name>Division</Name>
            <Number/>
            <Company/>
        </Keeper>
</Data>

Below is my 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="*[not(*)][not(normalize-space())]">
      <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:text>12345</xsl:text>
      </xsl:copy>
    </xsl:template>
   </xsl:stylesheet>

Please provide any solution or suggest a way to modify existing XSLT to avoid all the elements of <Makers> from getting modified.

The desired output should be like below where any empty node inside <Makers> is not modified but outside that all the empty nodes are modified with value "12345":

<Data>
       <Makers>
            <Type>ABC</Type>
            </Set>
            <Block>
                <FirstName>ZSPZCVCR</FirstName>
                <LastName/>
            </Block>
        </Makers>
        <Keeper>
            <Code>12</Node>
            <Name>Division</Name>
            <Number>12345</Number>
            <Company>12345</Company>
        </Keeper>
</Data>
2
How should the desired output look like? - zx485
Thanks for the reply. I modified my question to show the desired output. - Vikram

2 Answers

1
votes

you should add a predicate:

[not(ancestor::Makers)]

to your second template. Such as

<xsl:template match="*[not(*)][not(normalize-space())][not(ancestor::Makers)]">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:text>12345</xsl:text>
    </xsl:copy>
</xsl:template>
0
votes

My solution would be to add the template rule

<xsl:template match="Makers" priority="5">
  <xsl:copy-of select="."/>
</xsl:template>

To me this seems clearer than Joel's solution.