从Mac上的文件中删除XML部分

时间:2019-04-17 11:30:40

标签: xml bash command-line-interface

我在Mac上具有以下结构的xml文件

<?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>

我想拥有一个bash / cli脚本来从其中删除以下部分。

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

如何使用sed / awk / xmlstarlet执行此操作?

我尝试了以下方法。不会出现错误,但也不会执行任何操作。

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

下面也尝试了XMLSTARLET,但没有运气

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

1 个答案:

答案 0 :(得分:1)

使用XMLStarlet,可以执行以下命令:

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

注意::您可能需要将上面命令的初始xml部分替换为xmlstarlet < / p>

说明:

  1. 您的源xml包含一个Namespace(即文档元素的开始标记中的xmlns="http://test.com/data"声明),因此您需要利用XMLStarlet的-N选项在editing xml documents中使用ed命令对其进行预定义。

    如您在命令上方所见,读取的部分;

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

    使用名称d预定义命名空间。

  2. 读取部分:

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

    定义Xpath表达式以解决我们感兴趣的XML文档的部分-在这种情况下,它解决了我们要删除的元素。

    如您所见,每个对元素节点的引用都以d:为前缀

    本质上,这个 xpath 表达式;仅当它们具有名为userPermissions的子元素节点(其文本节点等于该单词)时,才匹配名为http://test.com/data(属于命名空间; name)的任何元素节点; "Delete"

  3. -d选项/标志用于删除Xpath表达式匹配的内容。

  4. -L选项/标志可就地编辑文件。 出于测试目的,您可能最初想删除此选项/标志。

结果

鉴于执行上述命令的源XML,将在名为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>