【问题标题】:xmlstarlet Remove nodes with duplicate attributesxmlstarlet 删除具有重复属性的节点
【发布时间】:2022-11-11 00:02:27
【问题描述】:

我正在尝试根据属性的值删除 xml 文件中的重复条目。

<?xml version='1.0' encoding='UTF-8'?>
<root>
  <entries>
    <entry name="entry1">
      <value>1</value>
    </entry>
    <entry name="entry1">     <-- Duplicate name here
      <value>2</value>
    </entry>
    <entry name="entry2">
      <value>3</value>
    </entry>
  </entries>
</root>

我想要以下

<?xml version='1.0' encoding='UTF-8'?>
<root>
  <entries>
    <entry name="entry1">
      <value>1</value>
    </entry>
    <entry name="entry2">
      <value>3</value>
    </entry>
  </entries>
</root>

我努力了

xmlstarlet edit --delete '/_:root/_:entries/*[@name = .//preceding-sibling::*/@name]'

但是xpath 与属性name="entry1" 的上一个条目不匹配

【问题讨论】:

  • 重复的条目总是一个接一个,还是可以用非重复的条目分隔?

标签: xml xpath xmlstarlet


【解决方案1】:

如果你可以使用 YAML 处理器mikefarah/yq,你的任务可以这样解决:

版本 < 4.30

yq --input-format xml --output-format xml e '.root.entries.entry |= unique_by(.+name)'

版本 >= 4.30

yq --input-format xml --output-format xml e '.root.entries.entry |= unique_by(.+@name)'

输出

<?xml version='1.0' encoding='UTF-8'?>
<root>
  <entries>
    <entry name="entry1">
      <value>1</value>
    </entry>
    <entry name="entry2">
      <value>3</value>
    </entry>
  </entries>
</root>

该解决方案的好处是数组中元素的顺序无关紧要。

【讨论】:

    【解决方案2】:

    您只需从preceding-sibling:: 中删除.//

    像这样:

    xmlstarlet edit --delete '/_:root/_:entries/*[@name = preceding-sibling::*/@name]' input.xml
    

    注意:我对此进行了测试,但需要向 XML 添加一个默认命名空间,以便 _ 命名空间前缀可以工作。如果您的实际输入中没有默认命名空间,请从 xpath 中删除 _:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多