XMLを読み取り、値のみを抽出する[重複]

XMLを読み取り、値のみを抽出する[重複]

XMLファイルに設定された値のみを抽出する最も簡単な方法は何ですか?たとえば、XMLファイルのデータは次のとおりです。

<node name="host">
  <map>
    <entry key="cipher_strength" value="low" />
    <entry key="port" value="78234" />
    <entry key="over_ssl" value="false" />
    <entry key="using_fips" value="true" />
    <entry key="ssl_keystore" value="lib/ssl" />
  </map>
</node>

lowスクリプトで表示したいです。

これはsed私が使用するコマンドで、文字列全体を返します。

sed -n '/cipher_strength/{s/.*<cipher_strength>//;s/<\/cipher_strength.*Value=""//;p;}' test.xml

コメントによると、xmlstarlet私の水洗バージョンでは利用できず、ベンダーがロックされていてインストールできないため、できません。

答え1

コマンドラインXMLパーサーの使用xmlstarlet

xmlstarlet sel -t -v '//entry[@key="cipher_strength"]/@value' -nl file.xml

entryこれはXML文書のすべてのノードと一致し、value同じentryノードにkey値がある属性がある場合はその属性値が抽出されますcipher_strength。各値は末尾の改行文字とともに出力されます。

xmllintさまざまなシステムで利用可能な実装は、XPathクエリの実行のサポートが多様であるようです。

私のOpenBSDシステムでは、次のことができます。

xmllint --xpath '//entry[@key="cipher_strength"]/@value' file.xml

検索する

 value="low"

しかし、xmllint --xpath '//entry[@key="cipher_strength"]/@value/text()' file.xml私はそれが私に文字列を与えることを期待していましたが、うまくいかないようlowです(ただXPath set is empty答えを生成するだけです)。

属性値が「nice」の場合、valueこの出力を処理して実際の値を抽出できます。

$ xmllint --xpath '//entry[@key="cipher_strength"]/@value' file.xml | sed -e 's/^[^"]*"//' -e 's/"$//'
low

上記の式は、sed各行から最初の二重引用符文字まですべてを削除し、最後の二重引用符文字も切り捨てます。

他のxmllint実装/バージョンでは、次のアプローチを採用している可能性がありますxmllint --shell

xmllint --shell file.xml <<<'cat //entry[@key="cipher_strength"]/@value' |
sed -e '/^[^ ]/d' -e 's/^[^"]*"//' -e 's/"$//'

答え2

専用のXMLツールが利用できない場合は、以下を試してくださいawk

user@host~$ awk '/key="cipher_strength"/ {for (i=1;i<=NF;i++) { if (split($i,parts,"=")==2 && parts[1]=="value") print parts[2]}}' file.xml

スペースで区切られたすべての文字列を含む行を検索し、スペースで区切られたすべてのkey="cipher_strength"文字列はシンボルから分割されます=。 「中間」にこのシンボルを含むすべてのシンボルについて(つまり、前に部分があり、後に部分がある)最初の部分が同じであることを確認し、valueそうであれば2番目の部分を印刷します。あなたの意見について

user@host~$ awk '/key="cipher_strength"/ {for (i=1;i<=NF;i++) { if (split($i,parts,"=")==2 && parts[1]=="value") print parts[2]}}' file.xml
"low"

ノードが多い場合は、<node>このタスクを適用する前にプログラムを変更して正しい場所にいることを確認できます。

関連情報