XMLStarlet,XPath - 如何根据节点删除属性

XMLStarlet, XPath - How to remove attributes depending on node

我正在尝试使用 XMLStarlet 对此进行转换 (test.xml):

<?xml version="1.0"?>
<root xmlns:doc="http://www.test.com" doc:id="hello">
  <a doc:id="x"/>
  <a doc:id="x"/>
  <c doc:id="x">
    <a doc:id="x"/>
    <a doc:id="x"/>
    <c doc:id="x"/>
  </c>
</root>

进入此(删除 c 以外所有节点上的 doc:id 属性):

<?xml version="1.0"?>
<root xmlns:doc="http://www.test.com" doc:id="hello">
  <a/>
  <b/>
  <c doc:id="hello">
    <a/>
    <b/>
    <c doc:id="hello"/>
  </c>
</root>

我试过了,但它删除了所有 doc:id 属性:

xml ed -N doc="http://www.test.com" -d "//@doc:id[not(self::c)]" test.xml

您可以使用这两个 xmlstarlet 命令的串联:

  1. 第一个删除 (-d) 所有 doc:id 不属于 <c> 元素的属性(正如您已经做的那样)
  2. 命令的第二部分更新(-u<c> 元素的所有 doc:id 属性的值(-v)。

这是命令:

xml ed -N doc="http://www.test.com" -d "//*[not(self::c)]/@doc:id" -u "//c/@doc:id" -v "hello" test.xml

输出如愿。