2
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

スタイルシートでXMLを変換する

この記事は「いのべこ(富士通システムズウェブテクノロジー)Advent Calendar 2020」の5日目の記事です。記事の掲載内容は私自身の見解であり、所属する組織を代表するものではありません(お約束)。

スタイルシートとスタイルシート

もう、10年以上前なので会話はうろ覚えですが
xmlファイルを加工して、csvにするにあたり、
こんな会話をしたことがありました。

私:Javaあたりで読み込んで加工しましょうか。
先輩:xmlの仕様が変わるかもしれないから、スタイルシートのほうがいいな。
私:え、スタイルシートですか。
先輩:そう。スタイルシート。
私:スタイルシートでそんなことできるんですか。
先輩:?!

2人のすれ違いがどういうことかわかるでしょうか。
当時私はwebアプリを中心にプログラマをやっていました。
私にとってスタイルシートはcssのことでした。
しかし、先輩が言っていたのはxsltのことでした。
つまり、こういうこと。

私:Javaあたりで読み込んで加工しましょうか。
先輩:xmlの仕様が変わるかもしれないから、スタイルシート(xlst)のほうがいいな。
私:え、スタイルシート(css)ですか。
先輩:そう。スタイルシート(xlst)。
私:スタイルシート(css)でそんなことできるんですか。
先輩:?!

見事に会話がかみ合ってませんね。用語定義大事です。

当時の私のようにcssしか知らない人もいるかもしれないということで、xsltについて紹介したいと思います。

XSLT(XSL Transformations)とは

参考文献「改訂 XML入門」によると下記のように書かれていました。

XSLT(XSL Transformations)は、XML文書をHTML形式・TEXT形式・別のXML形式に変換するための言語です。

Webアプリケーションを作る際に、HTMLにcssを追加してデザインを変更するように、
XMLファイルにxsltを追加するとデータを別の形式に変換できるようです。

具体例

参考にXMLファイル、XSLTスタイルシート、出力結果を作ってみました。
サンプルではソートしかしていませんが、連番を振ったり、繰り返し処理を追加したり色々な制御が可能です。

また、書いていたはまったところが2点ありました。うまく出力できないときの参考にして下さい。
1)ルート要素から順にたどるようにスタイルを定義していっているため、
例えばfruitbasketを飛ばして書くと何も出力されませんでした。
2)属性名とタグの違いを見落としており、属性名に@をつけ忘れて出力されないことがありました。

  • XMLファイル(fruit.xml)
<fruitbasket lang="ja">
    <contents>
        <fruit kind="banana"/>
        <fruit kind="apple">
         <variety>tsugaru</variety>
        </fruit>
        <fruit kind="melon"/>
        <fruit kind="grapes">
         <variety>muscat</variety>
        </fruit>
    </contents>
</fruitbasket>
  • XSLTの定義ファイル(fruitxslt.xsl)
<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:output method="text" encoding="Shift_JIS"/>

  <xsl:template match="/">
    <xsl:apply-templates select="fruitbasket"/>
  </xsl:template>

  <xsl:template match="fruitbasket">
    <xsl:apply-templates select="contents"/>
  </xsl:template>

  <xsl:template match="contents">
    <xsl:text>~お品書き~
</xsl:text>
    <xsl:apply-templates select="fruit">
        <xsl:sort select="@kind" />
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="fruit">
    <xsl:value-of select="@kind"/>
    <xsl:text>  </xsl:text>
    <xsl:value-of select="variety"/>
    <xsl:text>
</xsl:text>
  </xsl:template>

</xsl:stylesheet>
  • 実行結果(fruit.txt)
~お品書き~
apple   tsugaru
banana  
grapes  muscat
melon   

変換方法

手軽な方法として、サンプルではmsxslを使いました。

マイクロソフトのダウンロードサイトでmsxslを検索し、ダウンロードします。
msxmlではありません。ご注意ください(私は一度間違えて???ってなりました)。

ダウンロードしたexeファイルと、xmlとxslファイルをすべて同じフォルダに置き、
以下のコマンドを実行するとfruit.txtに結果が出力されます。

msxsl.exe fruit.xml fruitxslt.xsl -o fruit.txt

ほかにもJavaであれば javax.xml.transform.Transformerなどを用いてスタイルシートを使うと変換した結果を受け取ることができます。

Javaでスタイルシートを使わずにコーディングして、XMLのまま読み取って変換して出力することももちろん可能ですが、冒頭の会話のようにxmlの書式が変わる可能性がある場合や、あるいは出力指定形式が変わる可能性がある場合はスタイルシートとしてコードの外に定義しておくことでメンテナンス性が向上する利点があります。

最後に

非常にざっくりとした説明でしたが、xsltスタイルシートについてどのようなものか伝わりましたでしょうか。
最近はjson形式のデータが多くなり、XML形式のデータはだいぶ減ってきているように感じます。
減ってきてはいますが根強く残っているのもまた事実なので、こういった古い技術も忘れずに活用して、楽々プログラミングを目指したいものです。

参考文献

今回の記事は、冒頭の会話を受けてXSLT初挑戦したときに購入した下記の本を参考にしながら作成しました。
かなり古い本なので入手困難かもしれません…。

改訂 XML入門
ISBN4-88647-824-7

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
2
Help us understand the problem. What are the problem?