職場にて、古くからあるxml形式で保存されている表形式の定義ファイルを
DBに格納するためにcsv形式に変換にしたいが、やり方がわからないと部下に泣きつかれ、
10年ほど昔にXML資格試験の勉強したなぁと懐かしくなりつつ、
xmlの変換方法を調べたので、備忘もかねて記載します。
細かいxsl記載方法については、後日余裕があれば記載しなおします。
準備するファイル
- 読み込むxmlファイル(test.xml)
- 上記xmlファイルをparseしてcsv変換するXML定義:xsltファイル(csv.xsl)
前提環境:CentOS 7.x
利用コマンド:xsltproc
test.xmlの内容は以下の通りとします。
<?xml version="1.0" encoding="utf-8"?>
<root>
<path>/tmp</path>
<as>
<a>
<name>1</name>
<al>abc</al>
<date>2008-01-01</date>
</a>
<a>
<name>2</name>
<al>efg</al>
<date>2009-01-01</date>
</a>
<a>
<name>3</name>
<al>xyz</al>
<date>2010-01-01</date>
</a>
</as>
</root>
/root/as/a パス配下が表にかかわる定義で、name,al,dateといった列があるという前提です。
今回のパターンでは3パターンある状態です。
<path>/tmp</path>
については、/root/pathについては読み取らないことを確認するためのダミーデータとしています。
上記xmlファイルをcsv変換するXML定義(csv.xsl)を以下の通りに作ります。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="utf-8" />
<xsl:param name="delim" select="','" />
<xsl:param name="break" select="'
'" />
<xsl:template match="/">
<xsl:apply-templates select="root/as/a" />
</xsl:template>
<xsl:template match="a">
<xsl:apply-templates />
<xsl:value-of select="$break" />
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="*">
<xsl:value-of select="text()" />
<xsl:if test="following-sibling::*">
<xsl:value-of select="$delim" />
</xsl:if>
</xsl:template>
<xsl:template match="text()" />
</xsl:stylesheet>
(xslの詳細のリンク先をのちに貼ります。)
2つのファイルを準備したうえで、以下のコマンドを入力して、標準出力に出力します。
ファイル出力する場合は、リダイレクトで出力ファイルを出力するとよいでしょう。
$ xsltproc csv.xsl test.xml
出力結果は以下のようになりますので、DBに入れるなり、EXCELで処理するなり、
実施しやすくなると思います。
1,abc,2008-01-01
2,efg,2009-01-01
3,xyz,2010-01-01