首页 > 解决方案 > 尝试使用 xmlstarlet 删除元素但似乎没有做任何事情

问题描述

我正在运行以下命令

xmlstarlet ed -d "/Package/types[name='ApexEmailNotifications']" test.xml

针对以下 XML

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
  <types>
    <members>1</members>
    <name>ApexEmailNotifications</name>
  </types>
  <types>
    <members>2</members>
    <name>ApexTrigger</name>
  </types>
  <types>
    <members>3</members>
    <members>4</members>
    <name>AppMenu</name>
  </types>
  <version>50.0</version>
</Package>

期望它更改为以下

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
  <types>
    <members>2</members>
    <name>ApexTrigger</name>
  </types>
  <types>
    <members>3</members>
    <members>4</members>
    <name>AppMenu</name>
  </types>
  <version>50.0</version>
</Package>

但是什么也没发生我只是觉得我在这里或那里错过了一个愚蠢的角色​​,或者误解了手册页。

我的头发剩下的任何帮助将不胜感激

标签: xmlstarlet

解决方案


XML 名称空间通常使事情变得困难。这就是你在 xmlstarlet 中必须做的事情:声明命名空间(_下面没有什么神奇的,它只是一个名称),然后为每个标签使用前缀

xmlstarlet ed \
    -N _=http://soap.sforce.com/2006/04/metadata \
    -d "/_:Package/_:types[_:name = 'ApexEmailNotifications']" \
    test.xml

结果

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
  <types>
    <members>2</members>
    <name>ApexTrigger</name>
  </types>
  <types>
    <members>3</members>
    <members>4</members>
    <name>AppMenu</name>
  </types>
  <version>50.0</version>
</Package>

正如 Daniel Haley 评论的那样,由于命名空间适用于根元素,我们可以使用不带_, 的前缀来表示 xmlstarlet 版本 >= 1.2.1 -N

xmlstarlet ed -d "/_:Package/_:types[_:name = 'ApexEmailNotifications']"  test.xml

DEFAULT并且为相同目的提供了 1.5.0 版

xmlstarlet ed -d "/DEFAULT:Package/DEFAULT:types[DEFAULT:name = 'ApexEmailNotifications']"  test.xml

推荐阅读