使用xmllint,它是一个与 libxml2 捆绑在一起的命令行工具。很可能它在您的系统上可用。
根据您的示例数据(删除省略号),我玩弄并管理了以下内容:
echo -e "du\nbye\n" | \
xmllint --shell data
返回
/ > du
/
bookstore
book
title
price
retail
discounts
amazon
currency
/ > bye
这使用工具的交互模式。
du
要求打印从当前节点(此处为根)开始的整个子树。
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!"}
'
给
/bookstore/book/price/discounts/amazon
要解释这一点,请查看sed
命令后的输出:
/ > du
/
bookstore
: book
: : title
: : price
: : : retail
: : : discounts
: : : : amazon
: : : currency
/ > bye
sed
[two spaces]
用代替[:space]
。
在下文中,使用 检测深度很简单awk
。