尝试使用 xmlstarlet 删除元素但似乎没有做任何事情

Trying to use xmlstarlet to delete element but doesn't seem to be doing anything

我是运行下面的命令

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>

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

我的头发还剩下什么,将不胜感激

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 评论的那样,由于命名空间适用于根元素,我们可以使用 _ 前缀 而无需 -N,对于 xmlstarlet 版本 > = 1.2.1

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

和版本 1.5.0 提供 DEFAULT 出于同样的目的

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

另一种方式,使用local-name():

xml ed -d  '//*[local-name()="Package"]//*[local-name()="types"][.//*[local-name()="name"][./text()="ApexEmailNotifications"]]' test.xml