【问题标题】:How to parse xml sibling element value with SED [duplicate]如何使用 SED 解析 xml 兄弟元素值 [重复]
【发布时间】:2015-04-17 11:31:24
【问题描述】:

我有一个包含以下文本的 xml 文件:

<Cluster>
     <Name>CLS_20</Name>
     <JMXUserName>admin</JMXUserName>
     <JMXPassword>mypwd</JMXPassword>
</Cluster>
<Server>
    <Name>Server_20</Name>
    <IpAddress>a.b.c.d</IpAddress>
    <Port>1234</Port>
</Server>
<Server>
    <Name>Server_21</Name>
    <IpAddress>e.f.g.h</IpAddress>
    <Port>1234</Port>
</Server>

我有服务器的 IP 地址 (a.b.c.d) 我想检索服务器的名称(Server_20)

如何使用 SED 实现这一点 或者使用任何其他 linux 命令。

请帮忙。

【问题讨论】:

  • 选择一种具有 XML 解析器的语言。 (Python、Perl、Ruby 等)。

标签: linux bash sed


【解决方案1】:

由于结构有很多变化,但基于此示例,Sed 在 xml 上使用时要谨慎

sed -n '
 /<Server>/ h
 /<Server>/,\#</Server># {
   H
   \#</Server># { 
      x
      s#.*<Name>\([^<]*\)<.*IpAddress>a.b.c.d<.*#\1#p
      }
   }' YourFile

原理:

  • 除非明确要求,否则不要打印
  • 在缓冲区中加载部分Server
  • 到达部分末尾时
    • 通过仅保留名称属性来更改整体如果 ipadresse 值与 a.b.c 相同,在这种情况下打印结果

【讨论】:

    【解决方案2】:

    不要对 sed 执行此操作;当 XML 发生良性格式更改时,它会严重损坏。

    使用适当的 XML 解析工具。以 xmlstarlet 为例:

    xmlstarlet sel -t -c '//Server[IpAddress="a.b.c.d"]/Name/node()' -n filename.xml
    

    或使用 xmllint:

    xmllint --xpath '//Server[IpAddress="a.b.c.d"]/Name/node()' filename.xml
    

    或使用尚不了解 --xpath 的旧版本 xmllint(如果您想使用它,我鼓励您查看其他工具):

    echo 'cat //Server[IpAddress="a.b.c.d"]/Name/node()' | xmllint --shell filename.xml | sed '1d;$d'
    

    或使用来自XML::XPath Perl 库的xpath 实用程序:

    xpath -q -e '//Server[IpAddress="a.b.c.d"]/Name/node()' filename.xml
    

    ...或使用三打(十几种)其他 XML 工具中的任何一种。

    其核心是 XPath 表达式 //Server[IpAddress="a.b.c.d"]/Name/node()。这包括:

    • //Server 指的是文档中任意位置的 Server 节点
    • //Server/Name 指的是 Name 节点,它是此类 Server 节点的子节点
    • //Server/Name/node() 指的是这样一个Name 节点的内容
    • //Server[IpAddress="a.b.c.d"] 指的是满足条件IpAddress="a.b.c.d" 的服务器节点,这意味着它有一个包含a.b.c.d 的子节点IpAddress

    将所有这些放在一起,//Server[IpAddress="a.b.c.d"]/Name/node() 指的是 Name 节点的内容,该节点是文档中任何位置的 Server 节点的子节点,该节点具有包含 IpAddress 子节点的 IpAddress 子节点。

    【讨论】:

    • 当我使用 xxllint 时,它给了我未知的选项 --xpath:版本是 - xmllint:使用 libxml 版本 20706
    • 这似乎是 xmllint 的旧版本。哼。你身边还有其他 XML 处理工具吗?有很多可以过滤 XPath 表达式,所以我宁愿寻找一个工具来使用,而不是用 xmllint --shell 和 grep 破解一些脏东西。
    • 我不能使用第三方工具,因为它是客户机器。我正在寻找在脚本中解析该值的简单且可用的方法。
    • 好的,那么。我用旧的 xmllint 进行了编辑,但为了记录:我认为它不是很漂亮。比使用纯文本工具解析 XML 更好,但仍然如此。
    • 太棒了!非常感谢。
    猜你喜欢
    • 2020-12-17
    • 2020-04-28
    • 1970-01-01
    • 1970-01-01
    • 2016-07-28
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 2021-01-20
    相关资源
    最近更新 更多