13

XML ファイルから任意のデータをすばやく抽出して、CSV 形式にする必要がある場合があります。Unix ターミナルでこれを行うためのベスト プラクティスは何ですか? いくつかのコード例が欲しいのですが、たとえば、次の問題を解決するにはどうすればよいですか?

XML 入力の例:

<root>
    <myel name="Foo" />
    <myel name="Bar" />
</root>

私の望ましいCSV出力:

Foo,
Bar,
4

8 に答える 8

12

ピーターの答えは正しいですが、末尾の改行を出力します。

<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>&#xA;</xsl:text>
      </xsl:if>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

実行するだけ

xsltproc stylesheet.xsl source.xml

CSV 結果を標準出力に生成します。

于 2008-08-27T05:48:46.433 に答える
9

xsltprocsaxonまたはxalanなどのコマンドライン XSLT プロセッサを使用して 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>&#10;</xsl:text>
    </xsl:template> 
</xsl:stylesheet>
于 2008-08-26T21:40:02.943 に答える
7

XMLStarlet は、XML ドキュメントをクエリ/編集/チェック/変換するためのコマンド ライン ツールキットです (詳細については、「XMLStarlet コマンド ライン XML ツールキット」を参照してください) 。

ファイルを書き込む必要はありません。ファイルを xmlstarlet にパイプして、xpath フィルターを適用するだけです。

cat file.xml | xml sel -t -m 'xpathExpression' -v 'elemName' 'literal' -v 'elname' -n

-m 式 -v 値 '' 含まれるリテラル -n 改行

したがって、xpath の場合、xpath 式は //myel/@name となり、2 つの属性値が提供されます。

非常に便利なツールです。

于 2008-09-12T08:05:58.733 に答える
6

任意の要素の name 属性だけが必要な場合は、簡単ではあるが不完全な解決策があります。

(サンプルテキストはファイルのにあります)

grep "名前" の例 | カット -d"\"" -f2,2 | xargs -I{} エコー "{},"

于 2008-08-26T21:47:42.753 に答える
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'] }
于 2008-08-27T07:25:01.320 に答える
1

テスト ファイルは test.xml にあります。

sed -n 's/^\s`*`&lt;myel\s`*`name="\([^"]`*`\)".`*`$/\1,/p' test.xml

たとえば、各ミエルが1行にあることが厳密に指定されていない場合、最初にxmlファイルを「正規化」する必要があります(したがって、各ミエルは1つの個別の行にあります)

于 2008-09-18T08:40:35.137 に答える
1

xmlファイルが「test.xml」であると仮定して、元の質問に答えます。

<root>
<myel name="Foo" />
<myel name="Bar" />
</root>
cat text.xml | tr -s "\"" " " | awk '{printf "%s,\n", $3}'
于 2014-01-21T06:12:50.897 に答える