Xmllintで属性を指定してXmlから値を取得

またまたシェルスクリプトとxmllintを使う機会があった。

今度はxmlに同名タグが複数存在しており、属性で絞って値を取るというパターンだった。

やりたいこと

以下のxmlがあったとする。

<!-- sample.xml -->
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <long name="aaa" value="12345" >いぬ</long>
    <long name="bbb" value="56789" >ねこ</long>
</map>

longタグ内にあるname="aaa"のvalueの値「12345」を取得したい。

前回と同じくxmllintを使って取得する。

準備&おさらい

準備&おさらいとして、単にvalueのみを指定してxmllintで取る。

echo 'cat map/long/@value' | xmllint --shell sample.xml

結果はこうなる

/ > cat map/long/@value
 -------
 value="12345"
 -------
 value="56789"

name="aaa"もname="bbb"の両方のvalueがヒットしてしまう。
これを条件を与えて絞るようにする。

xmllintに条件を加える

name=aaaのみを得るには、long[@name="aaa"]とする。

echo 'cat map/long[@name="aaa"]/@value' | xmllint --shell sample.xml

とすると、結果はこうなる。

/ > cat map/long[@name="aaa"]/@value
 -------
 value="12345"

無事にname=aaaのみのvalueが取れた。

できた

あとは変数だけを取得するなら、自分はこうしてみた

value=`echo 'cat map/long[@name="aaa"]/@value' | xmllint --shell sample.xml |grep value= | sed 's/[^"]*"\([^"]*\)"[^"]*/\1/g'`
echo $value

結果はこうなる。

1234

これで目標達成となった。

<br

おまけ

「いぬ」の値を取る場合はこうした。

value=`echo 'cat map/long[@name="aaa"]' | xmllint --shell sample.xml | grep value= | sed 's/^.*<long.*>\(.*\)<\/long>.*$/\1/'`;
echo $value

結果はこうなる。

いぬ


参考リンク
- Test XML command line with xmllint | - Softwaretester -