libxml2にバンドルされているコマンドラインツールであるxmllintを使用します。お使いのシステムで利用できる可能性が非常に高いです。
サンプルデータ(省略記号を削除)に基づいて、私は次のことを試して管理しました。
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
です。