ShellScriptでXMLの内容を取り出す

こんにちは。itouです。
ShellScript(シェルスクリプト)でXMLをパースして内容を取り出すTIPSです。

環境はLinux(CentOS6.5)で検証します。
ツールは「xmllint」を使用します。
CentOS6.5だと「/usr/bin/xmllint」にプリインストールされています。
xmllintの本家サイトは「http://xmlsoft.org/」です。

まず、サンプルのXMLファイルを作成します。

・sample.xml

[code]
<?xml version="1.0" encoding="UTF-8"?>
<sample>
  <food>
    <name language="Japanese">りんご</name>
    <amount>105</amount>
  </food>
  <food>
    <name language="English">grape</name>
    <amount>210</amount>
  </food>
</sample>
[/code]

xmllintでサンプルXMLファイルを参照します。
“cat”でXMLの全内容を取得できます

[shell]
$ xmllint --shell sample.xml
/ > cat

<?xml version="1.0" encoding="UTF-8"?>
<sample>
  <food>
    <name language="Japanese">りんご</name>
    <amount>105</amount>
  </food>
  <food>
    <name language="English">grape</name>
    <amount>210</amount>
  </food>
</sample>
[/shell]

「sample」→「food」→「name」要素の内容を取得する場合は、下記のように指定します。

[shell]
/ > cat /sample/food/name
 -------
<name language="Japanese">りんご</name>
 -------
<name language="English">grape</name>
[/shell]

2番目の「food」要素に定義している「name」要素の内容を取得する場合は、下記のように指定します。

[shell]
/ > cat /sample/food[2]/name
<name language="English">grape</name>
[/shell]

「language」属性の内容を取得する場合は、下記のように指定します。

[shell]
/ > cat /sample/food/name/@language
 -------
 language="Japanese"
 -------
 language="English"
[/shell]

ShellScriptで取得する場合など、非対話で実施する場合は、下記のようにします。

[shell]
$ echo "cat /sample/food/name" | xmllint --shell sample.xml
/ >  -------
<name language="Japanese">りんご</name>
 -------
<name language="English">grape</name>
[/shell]

各項目をxmllintにて取得し整形して表示するshellを作成しました。
xmllintによりXML要素の内容を取得し、sedで整形しています。
・sample.sh

[shell]
#!/bin/sh
count=1
while :
do
  # 食べ物の名称を取得
  name_xml=`echo "cat /sample/food[${count}]/name" | xmllint --shell sample.xml`

  # 食べ物の名称の言語を取得
  language_xml=`echo "cat /sample/food[${count}]/name/@language" | xmllint --shell sample.xml`

  # 食べ物の金額を取得
  amount_xml=`echo "cat /sample/food[${count}]/amount" | xmllint --shell sample.xml`

  # 全て取得した場合、ループを抜ける
  if [  "${name_xml}" = "/ > / > " ]; then
    break
  fi

  # 取得内容を整形
  language=`echo ${language_xml} | sed -e "s/^.*language=\"\(.*\)\".*$/\1/"`
  name=`echo ${name_xml} | sed -e "s/^.*<name.*>\(.*\)<\/name>.*$/\1/"`
  amount=`echo ${amount_xml} | sed -e "s/^.*<amount.*>\(.*\)<\/amount>.*$/\1/"`

  # 取得結果を表示
  echo ${name}"("${language}")"の金額は"${amount}円"

  count=${count}+1
done
[/shell]

実行結果です

[code]
りんご(Japanese)の金額は105円
grape(English)の金額は210円
[/code]

ShellScriptでXMLの内容を取得したい場合
xmllintは選択肢の一つになると思います。