Search code examples
xmlxsltxml-namespacesxmlstarlet

XMLStarlet delete parent node


I'm new using XMLStarlet and I'm wondering whether there is the possibility to remove a parent node that has a child with a specific value inside his tag.

In my example, I want to remove the node "<tabVisibilities>" that has inside a child node "<tab>" with the specfic value "SecondTab":

Starting XML:

<?xml version="1.0" encoding="UTF-8"?>
<Profile xmlns="http://soap.sforce.com/2006/04/metadata">
    <tabVisibilities>
        <tab>FirstTab</tab>
        <visibility>DefaultOn</visibility>
    </tabVisibilities>
    <tabVisibilities>
        <tab>SecondTab</tab>
        <visibility>DefaultOn</visibility>
    </tabVisibilities>
    <tabVisibilities>
        <tab>ThirdTab</tab>
        <visibility>DefaultOff</visibility>
    </tabVisibilities>
</Profile>

Expected XML:

<?xml version="1.0" encoding="UTF-8"?>
<Profile xmlns="http://soap.sforce.com/2006/04/metadata">
    <tabVisibilities>
        <tab>FirstTab</tab>
        <visibility>DefaultOn</visibility>
    </tabVisibilities>
    <tabVisibilities>
        <tab>ThirdTab</tab>
        <visibility>DefaultOff</visibility>
    </tabVisibilities>
</Profile>

Thank you very much, Davide.


Solution

  • Your file uses namespaces.

    xmlstarlet edit -N ns='http://soap.sforce.com/2006/04/metadata' --delete "//ns:tabVisibilities[ns:tab[contains(text(),'SecondTab')]]" file.xml
    

    Output:

    <?xml version="1.0" encoding="UTF-8"?>
    <Profile xmlns="http://soap.sforce.com/2006/04/metadata">
      <tabVisibilities>
        <tab>FirstTab</tab>
        <visibility>DefaultOn</visibility>
      </tabVisibilities>
      <tabVisibilities>
        <tab>ThirdTab</tab>
        <visibility>DefaultOff</visibility>
      </tabVisibilities>
    </Profile>
    

    See: xmlstarlet edit --help