XSLT Copy all Nodes except 1 element
Asked Answered
P

2

12
<events>
    <main>
        <action>modification</action>
        <subAction>weights</subAction>
    </main>
</events>
<SeriesSet>
    <Series id="Price_0">
        <seriesBodies>
            <SeriesBody>
                <DataSeriesBodyType>Do Not Copy</DataSeriesBodyType>
            </SeriesBody>
        </SeriesBodies>
    </Series>
</SeriesSet>

How do i copy all xml and exclude the DataSeriesBodyType element

Perilymph answered 20/2, 2013 at 16:38 Comment(0)
I
26

You just have to use the identity template (as you were using) and then use a template matching DataSeriesBodyType which does nothing.

The code would be:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">


    <xsl:output method="xml" encoding="utf-8" indent="yes"/>

    <!-- Identity template : copy all text nodes, elements and attributes -->   
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

    <!-- When matching DataSeriesBodyType: do nothing -->
    <xsl:template match="DataSeriesBodyType" />

</xsl:stylesheet>

If you want to normalize the output to remove empty data text nodes, then add to the previous stylesheet the following template:

<xsl:template match="text()">
    <xsl:value-of select="normalize-space()" />
</xsl:template>
Interfere answered 20/2, 2013 at 17:13 Comment(3)
I have tried that but its returning the element without a value. i dont want the element to be displayed at all.Perilymph
The XML that you posted is not the complete XML and it has some errors in it (e.g. seriesBody whith a closing tag SeriesBody) so I have checked my code with a corrected version of your XML (which maybe is not the same). Check that the name if the match="DataSeriesBodyType" matches exactly (upper case and lower case letters included) and if it is not working, post your complete XML.Interfere
And which element are you trying to exclude DataSeriesBodyType or SeriesBodyType? Just replace on the <xsl:template match="DataSeriesBodyType" /> the match attribute value with the XML element name to be excluded.Interfere
S
1

The following works for me as sometimes I need to create a tree without one element to make a variable and some times remove another to make another variable. Note that the main match should not match the root element "/" because if you do, it copies the whole three down only when processing just the one root element. But keep in-mind this solutions where we use apply-templates for all nodes will interfere with other templates you may have to do other jobs, so you would need to us the "mode" option to separate them.

    <xsl:template match="node()|@*">
       <xsl:copy>
         <xsl:apply-templates select="node()[not(self::DataSeriesBodyType)]|@*"/>
       </xsl:copy>
    </xsl:template>
Slovak answered 25/9, 2021 at 17:57 Comment(4)
Not a very efficient solution. It would be better to leave the identity transform template as is, and add a template matching the parent element of the element you want to remove that does the above.Pignus
Can you show me, please.Xhosa
See xsltfiddle.liberty-development.net/nbiE1bePignus
Thanks Michael. That's great. Would posted yourself as that is your solution?Xhosa

© 2022 - 2024 — McMap. All rights reserved.