UNIX ターミナルを使用した XML の解析
質問
XML ファイルから任意のデータをすばやく抽出して CSV 形式に変換する必要がある場合があります。Unix ターミナルでこれを行うためのベスト プラクティスは何ですか?いくつかのコード例が欲しいのですが、たとえば次の問題を解決するにはどうすればよいですか?
XML 入力の例:
<root>
<myel name="Foo" />
<myel name="Bar" />
</root>
希望する CSV 出力:
Foo,
Bar,
解決
要素の name 属性だけが必要な場合は、簡単ではありますが不完全な解決策を次に示します。
(サンプルテキストはファイル内にあります 例)
grep "name" Example | cut -d "" "-f2,2 | xargs -i {} echo" {}、 "
他のヒント
ピーターの答え は正しいですが、末尾に改行が出力されます。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text"/>
<xsl:template match="root">
<xsl:for-each select="myel">
<xsl:value-of select="@name"/>
<xsl:text>,</xsl:text>
<xsl:if test="not(position() = last())">
<xsl:text>
</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
たとえば、実行するだけです。
xsltproc stylesheet.xsl source.xml
CSV 結果を標準出力に生成します。
次のようなコマンドライン XSLT プロセッサを使用します。 xsltproc, サクソン人 または ザラン XML を解析して CSV を生成します。こちらです 例, 、あなたの場合、これはスタイルシートです:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="root">
<xsl:apply-templates select="myel"/>
</xsl:template>
<xsl:template match="myel">
<xsl:for-each select="@*">
<xsl:value-of select="."/>
<xsl:value-of select="','"/>
</xsl:for-each>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
XmlStarletは、XMLドキュメントをクエリ/編集/チェック/変換するコマンドラインツールキットです(詳細については、 http://xmlstar.sourceforge.net/)
書き込むファイルはありません。ファイルを xmlstarlet にパイプして xpath フィルターを適用するだけです。
cat file.xml | xml sel -t -m 'xpathExpression' -v 'elemName' 'literal' -v 'elname' -n
-m Expression -V Value '' LITERAL -N NEWLINEが含まれています
したがって、Xpathの場合、Xpath式は// Myel/@@nameで、2つの属性値を提供します。
とても便利なツールです。
これは、これを行う小さな Ruby スクリプトです。 その通り 質問の内容 (「myel」という要素から「name」という属性を取得します)。一般化するのは簡単なはずです
#!/usr/bin/ruby -w
require 'rexml/document'
xml = REXML::Document.new(File.open(ARGV[0].to_s))
xml.elements.each("//myel") { |el| puts "#{el.attributes['name']}," if el.attributes['name'] }
XML ファイルが次の内容を含む「test.xml」であると仮定して、元の質問に回答します。
<root>
<myel name="Foo" />
<myel name="Bar" />
</root>
cat text.xml | tr -s "\"" " " | awk '{printf "%s,\n", $3}'
テストファイルはtest.xmlにあります。
sed -n 's/^\s`*`<myel\s`*`name="\([^"]`*`\)".`*`$/\1,/p' test.xml
たとえば、それぞれの条件が厳密に与えられていない場合、落とし穴があります。 ミエル は 1 行にあります。最初に XML ファイルを「正規化」する必要があります (つまり、それぞれ ミエル は 1 つの別の行にあります)