てくてっく

コマ撮り作家系エンジニアです。日々地味ぃぃぃにつまづく技術的な問題について、備忘録として作ります。

XMLをCSVに変換したいときはXSLT

 

やはりあったXML変換

構造化されたデータを分解して一覧にするとか、
別のシステムに喰わせるために整形するとかで、
XML形式のデータをcsvに変換したいという要望がありました。

やったことなかったけど、なんかあるでしょと思ったらやはりあった。
qiita.com

 

xslt という方式を使います。
f:id:nikuniku9:20190226133315p:plain

 

XSLTとは

XSLTは、テンプレートファイルに沿ってXMLを処理するというものです。

今回はXMLCSVなので、項目ごとにカンマ付きのデータを生成し、

リダイレクトしてcsvファイルを作ります。

 

テンプレートファイルの作り方

XSLファイルを作成し、コマンドを打ちます。

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>
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>


上記のようにテンプレートファイル(.xsl)と元のファイル(.xml)を用意し、
コマンドを打つと結果が標準出力になります。


実行コマンド

xsltproc csv.xsl test.xml


結果

niku9:xmltest niku9$ xsltproc csv.xsl test.xml

1,abc,2008-01-01

2,efg,2009-01-01

3,xyz,2010-01-01

 

あとは使いやすいようファイルにリダイレクトしたりすれば良いです。