Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

xmlstarlet: filter out element with attribute

How to filter out elements of certain type which to not have an attribute with a magic value and retain the rest of the document? All this using xmlstarlet?

What I have to far is:

cat << EOF > database.xml
<?xml version="1.0"?>
<database>

    <some name="A" />
    <some name="B" />
    <some name="C" />
    <text>this is some text to be applied...</text>
    <project>
        <test deeper="structure"/>
    </project>

</database>
EOF

and

xmlstarlet sel -t -m "*" -c "*[not(self::some[@name != 'A'])]" database.xml

yields

<some name="A"/><text>this is some text to be applied...</text><project>
        <test deeper="structure"/>
    </project>

But this hides my precious <database> tag. Besides the indentation, which is not a problem... And doesn't work when <some> are not a direct descendant of <database>, childs of <project> for example.

What I want to get is the database as it is, but all <some> removed except the one named A:

<database>

    <some name="A" />


    <text>this is some text to be applied...</text>
    <project>
        <test deeper="structure"/>
    </project>

</database>

Greetings

like image 889
klsdjfhsalkjfhl Avatar asked Feb 01 '26 12:02

klsdjfhsalkjfhl


2 Answers

Unfortunately, xmlstarlet's sel doesn't support apply-templates, but you can use the ed command for this:

xmlstarlet ed -d '/database//some[@name != "A"]' input.xml
like image 164
npostavs Avatar answered Feb 03 '26 01:02

npostavs


Write an XSLT stylesheet doing

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

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

<xsl:template match="some[@name != 'A']"/>

</xsl:stylesheet>

then call xmlstarlet to apply that stylesheet to your input XML: xmlstarlet tr sheet.xsl input.xml.

like image 21
Martin Honnen Avatar answered Feb 03 '26 02:02

Martin Honnen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!