Search code examples
xmlxml-parsingxmllint

Remove a block of lines from xml file using xmllint


I have Test.xml file, which has following content.

<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright XXXXXX -->
<services>
    <service>
        <ServiceName>service1</ServiceName>
        <ServiceId>100</ServiceId>
    </service>
    <service>
        <ServiceName>service2</ServiceName>
        <ServiceId>200</ServiceId>
    </service>
    <service>
        <ServiceName>service3</ServiceName>
        <ServiceId>300</ServiceId>
    </service>
</services>

Based on the service name, i have to remove the entire block of that service.

Suppose, service1 is name i got as input, then following block should be removed from the xml.

<service>
    <ServiceName>service1</ServiceName>
    <ServiceId>100</ServiceId>
</service>

I can do this by using awk/sed/grep. But i should make use of xmllint or some other xml parsing utility here.

After research i could come closure to the output using below command. But, xml version and parent tags(services) are missing in the output.

xmllint --xpath "//services/service[ServiceName!='service1']" Test.xml

Solution

  • xmlstarlet solution:

    xmlstarlet ed -d "//service[ServiceName='service1']" test.xml
    

    The output:

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- Copyright XXXXXX -->
    <services>
      <service>
        <ServiceName>service2</ServiceName>
        <ServiceId>200</ServiceId>
      </service>
      <service>
        <ServiceName>service3</ServiceName>
        <ServiceId>300</ServiceId>
      </service>
    </services>
    

    • //service[ServiceName='service1'] - xpath expression, selects service node which has child node ServiceName with value service1

    To modify the file "inplace" - add -L option: xmlstarlet ed -L ...