Remove XML section from a file on a mac

Asked by At

I have a file xml file with the below structure on mac

<?xml version="1.0" encoding="UTF-8"?>
<Profile xmlns="http://test.com/data">
    <userPermissions>
        <enabled>true</enabled>
        <name>View</name>
    </userPermissions>
    <userPermissions>
        <enabled>true</enabled>
        <name>Edit</name>
    </userPermissions>  
    <userPermissions>
        <enabled>true</enabled>
        <name>Delete</name>
    </userPermissions>  
</Profile>

I would like to have a bash/cli script to remove the below section from it.

<userPermissions>
    <enabled>true</enabled>
    <name>Delete</name>
</userPermissions>  

How can I do this with sed/awk/xmlstarlet ?

I tried the below. Don't get an error but it does not do the job either.

sed -i '' 's#</userPermissions><userPermissions><enabled>true</enabled><name>Delete</name></userPermissions>#</userPermissions>#' FileName.Profile

sed -i '' 's/<\/userPermissions><userPermissions><enabled>true<\/enabled><name>Delete<\/name><\/userPermissions>/<\/userPermissions>/' FileName.Profile

tried below with XMLSTARLET as well but no luck

XMLStarlet ed --ps -d "/Profile/userPermissions[name='Delete'] FileName.profile"

1 Answers

1
RobC On Best Solutions

Using XMLStarlet you can execute the following command:

xml ed -L -N d="http://test.com/data" -d "d:Profile/d:userPermissions[child::d:name[.='Delete']]" FileName.profile

Note: You may need to replace the initial xml part of the command above with xmlstarlet

Explanation:

  1. Your source xml includes a Namespace, (i.e. the xmlns="http://test.com/data" declaration in the document element's start-tag), so you'll need to utilize XMLStarlet's -N option to predefine it when editing xml documents using the ed command.

    As you can see in the command (above) the part that reads;

    -N d="http://test.com/data"
    

    predefines the Namespace using the name d.

  2. The part that reads:

    "d:Profile/d:userPermissions[child::d:name[.='Delete']]"
    

    defines the Xpath expression to address the part(s) of the XML document that we're interested in - in this scenario it addresses the element(s) that we want to delete.

    As you can see each reference to an element node is prefixed with d:

    Essentially, this xpath expression; matches any element nodes named userPermissions (belonging to the Namespace; http://test.com/data) only if they have a child element node named name whose text node equals the word; "Delete".

  3. The -d option/flag is used to delete what the Xpath expression matches.

  4. The -L option/flag edits the file inplace. You may want to initially remove the this option/flag for test purposes.

Result

Given your source XML executing the command (above) will produce the following in the file named FileName.Profile:

<?xml version="1.0" encoding="UTF-8"?>
<Profile xmlns="http://test.com/data">
  <userPermissions>
    <enabled>true</enabled>
    <name>View</name>
  </userPermissions>
  <userPermissions>
    <enabled>true</enabled>
    <name>Edit</name>
  </userPermissions>
</Profile>