Home > Software design >  Remove nodes, selected by child values
Remove nodes, selected by child values

Time:09-16

I am trying in vain to develop a selection criterion that allows me to remove a node from an xml, or to create an xml that does not contain this node. The selection criterion should be a value somewhere below the node.

The example is simplified, but differs only from the node number and depth. In this example I want to remove all cars, which have 'VW' as manufacturer.

My (unsuccessful) attempts went roughly in the following direction:

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

        <xsl:copy-of select="*[not(self::car[manufacturer = 'VW'])]"/>

    </xsl:template>
</xsl:stylesheet>

original:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <cars>
        <car>
            <manufacturer>Audi</manufacturer>
        </car>
        <car>
            <manufacturer>VW</manufacturer>
        </car>
        <car>
            <manufacturer>Lada</manufacturer>
        </car>
    </cars>
</root>

aspired result:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <cars>
        <car>
            <manufacturer>Audi</manufacturer>
        </car>
        <car>
            <manufacturer>Lada</manufacturer>
        </car>
    </cars>
</root>

CodePudding user response:

Here's one way you could look at it:

XSLT 1.0

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

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

<xsl:template match="car[manufacturer = 'VW']"/>

</xsl:stylesheet>

Here's another:

XSLT 1.0

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

<xsl:template match="/root">
    <xsl:copy>
        <cars>
            <xsl:copy-of select="cars/car[not(manufacturer = 'VW')]"/>
        </cars>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

And another:

XSLT 1.0

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

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

<xsl:template match="cars">
    <xsl:copy>
        <xsl:apply-templates select="car[not(manufacturer = 'VW')]"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>
  • Related