web-dev-qa-db-ja.com

xmllintとXPathを使用して属性から値を取得するにはどうすればよいですか?

名前の値を取得し、XMLLintを使用して変数に入れたい

<body>
<value name="abc"></value>
</body>

echo 'cat //body/value/@name' | xmllint --Shell "test.xml"

/ >  -------
 name="abc"
/ > 

したがって、値「abc」を変数$ testに割り当てたい

30
Tran Ngu Dang

fn:string() を使用する必要があります。これは、引数の値をxs:stringとして返します。引数が属性の場合、属性の値をxs:stringとして返します。

test=$(xmllint --xpath "string(//body/value/@name)" test.xml)
28
h0li0

これを試してください、それは美しくはありませんが、動作します:)

>を含む行をstdoutから削除し、文字列をカットして=の後の2番目の部分を取得し、

test=$(echo 'cat //body/value/@name' | xmllint --Shell "test.xml" | grep -v ">" | cut -f 2 -d "=" | tr -d \"); 
echo $test
8
ego

複数の属性をサポートするhelper awkコマンドによるアプローチ( ego'sの合理化されたバージョンアプローチ ):

echo 'cat //*/@name' | xmllint --Shell file | awk -F\" 'NR % 2 == 0 { print $2 }'

awkコマンド:

  • xmllintの出力行を"文字でフィールドに分割します。 (-F\"

    • 入力に"..."が含まれていたとしても、xmllintは出力の属性値の引用符を'...'に正規化するため、"で分割するだけで十分です。
  • 偶数行(NR %2 == 0)のみを処理するため、catが常に出力する区切り線を除外します。

  • print $2は2番目のフィールドのみを出力します。これは、"..."を含まない各属性のvalueです。

fileに次のサンプルXMLがあると仮定します。

<body>
  <value name="abc"></value>
  <value name="def"></value>
</body>

上記の結果:

abc
def
5
mklement0

--xpathを使用して、この機能を持たないプラットフォームに元のシンプルなソリューションを移植する必要があったため、「cat」ソリューションも採用する必要がありました。これにより、Ubuntu 12.04およびSolaris 11でテストされた複数の一致が処理されます。

getxml() { # $1 = xml file, $2 = xpath expression
    echo "cat $2" | xmllint --Shell $1 |\
    sed -n 's/[^\"]*\"\([^\"]*\)\"[^\"]*/\1/gp'
}

例えばglassfishドメイン設定からインスタンス名を抽出する:

$ getxml /tmp/test.xml "//server[@node-ref]/@name"
inst1
inst2

Sed後処理では、引用符で囲まれた値をすべて取得しますが、これは私のニーズに十分でした(glassfishの設定を少し取得します)。

4
steve.sims