Tro*_*vey 2 xml macos bash xpath
鉴于这个大型深层嵌套XML文档(bookstore.xml)的片段,我想知道amazon节点的完整路径.如何从命令行打印该路径?
<bookstore>
<book>
<title lang="eng">Learning XML</title>
<price>
<retail>39.95</retail>
<discounts>
<amazon>29.99</amazon>
</discounts>
<currency>USD</currency>
</price>
</book>
...
</bookstore>
Run Code Online (Sandbox Code Playgroud)
理想情况下它看起来像这样:
old-gregg$ magic bookstore.xml amazon
/bookstore/book/price/discounts/amazon
Run Code Online (Sandbox Code Playgroud)
我发现了XMLStarlet,它正是我正在寻找的东西.使用Homebrew安装它:
$ brew update
$ brew install xmlstarlet
$ xml el bookstore.xml | grep amazon
/bookstore/book/price/discounts/amazon
Run Code Online (Sandbox Code Playgroud)
使用xmllint,它是与libxml2捆绑在一起的命令行工具.很可能它在您的系统上可用.
根据您的示例数据(删除省略号),我玩了并管理以下内容:
echo -e "du\nbye\n" | \
xmllint --shell data
Run Code Online (Sandbox Code Playgroud)
返回
/ > du
/
bookstore
book
title
price
retail
discounts
amazon
currency
/ > bye
Run Code Online (Sandbox Code Playgroud)
这使用工具的交互模式.
du要求从当前节点(此处为root)开始打印整个子树.
bye刚退出程序.
下一步是解析此输出.
更新:(
假设XML在其中data)
请注意,有问题的节点当前是硬编码的!
#!/bin/bash
echo -e "du\nbye\n" | \
xmllint --shell data | \
sed 's/ /: /g' | \
awk '
BEGIN {depth = 0}
$NF == "amazon" {
for(i=1; i<NF; i++) {printf("/%s", STACK[i])}
print "/" $NF
}
/^\// {next}
NF == depth + 1 {depth = NF; STACK[depth] = $NF; next}
NF == depth {STACK[depth] = $NF; next}
NF < depth {depth = NF; STACK[depth] = $NF; next}
1 {print "something went horribly wrong!"}
'
Run Code Online (Sandbox Code Playgroud)
给
/bookstore/book/price/discounts/amazon
Run Code Online (Sandbox Code Playgroud)
要解释一下这个sed命令之后的输出:
/ > du
/
bookstore
: book
: : title
: : price
: : : retail
: : : discounts
: : : : amazon
: : : currency
/ > bye
Run Code Online (Sandbox Code Playgroud)
sed替代[two spaces]用[:space].
在下文中,用它来检测深度很简单awk.
| 归档时间: |
|
| 查看次数: |
5781 次 |
| 最近记录: |