XSLT変換

XMLを変換する方法はいくつかあるけど、比較的簡単なXSLTを使ってXMLをHTMLに変換してみる。

全体イメージ的には↓こんな感じになる。


┌─────┐ ┌─────┐ ┌────────┐
│[1]入力XML│ │[2]XSL  │ │[5]出力ファイル │
│ファイル ├→│ファイル ├→│HTML,XML,CSV等 │
└─────┘ └─────┘ └────────┘
           ↑
        ┌──┴──┐
        │[3]変換  │
        │プログラム│
        ├─────┤
        │[4]XSLT  │
        │プロセッサ│
        └─────┘

 




 

[1] 入力ファイル

まず、入力XMLファイルについて。
どうせ作るなら少し実用的なモノがいいということで、価格.comのWebサービス(REST)で
返されるXMLファイルを使ってみることにした。

例えば、「iPod」を調べるためには、以下のようなURLをリクエストする。
http://api.kakaku.com/Ver1/ItemSearch.asp?Keyword=iPod
# URLエンコードするとか、そういう細かい話は今回割愛するので、
# keywordに全角、空白等は無しということで。

すると、検索結果として以下のXMLが返されてくる。
今回は、このXMLを入力ファイルとして扱ってみる。

<?xml version="1.0" encoding="utf-8" ?>
<ProductInfo>
  <NumOfResult>151</NumOfResult>
  <Item>
    <ProductID>01309511986</ProductID>
    <ProductName>iPod touch MA627J/A (16GB)</ProductName>
    <MakerName>APPLE</MakerName>
    <CategoryName>パソコン周辺機器>MP3プレーヤー</CategoryName>
    <PvRanking>1</PvRanking>
    <ImageUrl>
      http://img.kakaku.com/images/productimage/m/01309511986.jpg
    </ImageUrl>
    <ItemPageUrl>http://kakaku.com/item/01309511986/</ItemPageUrl>
    <BbsPageUrl>http://bbs.kakaku.com/bbs/01309511986/</BbsPageUrl>
    <ReviewPageUrl>
      http://kakaku.com/prdevaluate/evaluate.asp?PrdKey=01309511986
    </ReviewPageUrl>
    <LowestPrice>45800</LowestPrice>
    <NumOfBbs>1380</NumOfBbs>
  </Item>
    :
</ProductInfo>

[2] XSLファイル

次に、変換パターンを決めるXSLファイル。
XSLファイル自体もXMLで記述されていて、このXSLファイルにフォーマット変換のルールを定義する。
今回は、価格.comから返された結果を変換する。
[1]入力ファイル(XML)内のタグをHTMLのどこに割り当てるかルールを定義する。

例えば、XML内の
/ProductInfo/Item/ItemPageUrl をリンク先
/ProductInfo/Item/ProductName を商品名
とし、これをHTMLで利用する。
こんな感じ⇒ <a href=”リンク先”>商品名</a>

これをXSLで書くと↓こんな感じになる。

<a >
  <xsl:attribute name="href"><xsl:value-of select="ItemPageUrl"/></xsl:attribute>
  <xsl:value-of select="ProductName"/>
</a>

その他のタグについても変換ルールを決める。
ちなみに、↓これはくしけん用XSLを簡略化したもの。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
        version="1.0">
 <xsl:output method="html"/>
 <xsl:template match="/">
  <html lang="ja">
   <head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
    <meta http-equiv="Content-Style-Type" content="text/css" />
    <title><xsl:value-of select="/ProductInfo/Keyword" /></title>
   </head>
   <body>

    <!-- ページのリンク作成(10個まで) -->
    <xsl:variable name="pageNo" select="/ProductInfo/Page"/>
    <!-- 総ページ数=総件数÷1ページ辺りの表示件数(5件) -->
    <xsl:variable name="pageMax" select="/ProductInfo/NumOfResult div 5"/>
    <xsl:apply-templates select="/ProductInfo/Item" />

    <!-- 検索結果=0件の場合 -->
    <xsl:if test="$pageMax = 0">
     該当なし<br />
    </xsl:if>

   </body>
  </html>
 </xsl:template>

 <!-- アイテムごとの処理 -->
 <xsl:template match="Item">
  <table width="100%" style="border-collapse:collapse;border:none">
   <tr>
    <!-- trタグのstyle属性 -->
    <xsl:variable name="itemCnt"><xsl:number /></xsl:variable>
    <xsl:if test="$itemCnt mod 2 = 1">
     <!-- 奇数番目の背景色を変える -->
     <xsl:attribute name="style">background:#EEEEEE</xsl:attribute>
    </xsl:if>
    <td>

     <!-- aタグ -->
     <a target="_blank">
      <!-- aタグの href属性 -->
      <xsl:attribute name="href"><xsl:value-of select="ItemPageUrl"/></xsl:attribute>
       <!-- imgタグ -->
       <img border="0">
        <xsl:attribute name="src">
         <xsl:value-of select="ImageUrl" disable-output-escaping="yes"/>
        </xsl:attribute>
       </img>
     </a>

    </td>
    <td width="100%">
     <!-- URL、品名と値段 -->
     <a target="_blank">
      <xsl:attribute name="href"><xsl:value-of select="ItemPageUrl"/></xsl:attribute>
       <xsl:value-of select="ProductName"/>
     </a>
     <br />
     ¥<xsl:value-of select="LowestPrice"/>
    </td>
   </tr>
   <tr>
    <!-- trタグのstyle属性 -->
    <xsl:variable name="itemCnt"><xsl:number /></xsl:variable>
    <xsl:if test="$itemCnt mod 2 = 1">
     <!-- 奇数番目の背景色を変える -->
     <xsl:attribute name="style">background:#EEEEEE</xsl:attribute>
    </xsl:if>

    <td colspan="2">
     <a target="_blank">
      <xsl:attribute name="href"> 
       <xsl:value-of select="ReviewPageUrl" disable-output-escaping="yes"/>
      </xsl:attribute>
     レビュー記事
     </a>
     <br />
     メーカー:<xsl:value-of select="MakerName" disable-output-escaping="yes"/><br />
     カテゴリ:<xsl:value-of select="CategoryName" disable-output-escaping="yes"/>
          (<xsl:value-of select="PvRanking" disable-output-escaping="yes"/>位)<br />
     クチコミ:<a target="_blank">
           <xsl:attribute name="href"> 
            <xsl:value-of select="BbsPageUrl" disable-output-escaping="yes"/>
           </xsl:attribute>
          <xsl:value-of select="NumOfBbs" disable-output-escaping="yes"/>件
          </a><br />
    </td>
   </tr>
  </table>
  <br /><br />
 </xsl:template>
</xsl:stylesheet>

[3] 変換プログラム/[4] XSLTプロセッサ

XSLファイルを変換させるためには、XMLプロセッサ(XSLT)が必要。
XSLTは、Java、.NET、PHP、Webブラウザ(JavaScript)など、様々な言語で用意されている。
今回はC#(.NET)を利用してみるが、他の言語で利用したとしても、[1],[2]のファイル内容は変わらない。
プログラムはいたって簡単。
入力XMLファイル、XSLファイル、出力ファイルを指定するぐらい。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.Xml.Xsl;
using System.Xml;
using System.Diagnostics;

namespace xml2html
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // XSLT変換
            try
            {
                XslCompiledTransform xslt = new XslCompiledTransform();
                xslt.Load(textBoxXsl.Text);

                // XSLT変換
                string outFile = "result.htm";
                xslt.Transform(textBoxXml.Text,outFile);
                Process.Start(outFile);
            }
            catch (Exception ex)
            {
                MessageBox.Show("XSLT変換に失敗しました。\n\n" + ex.Message,
                                "XSLT", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }

        }
    }
}

# textBoxXml.Textには入力XML、textBoxXsl.TextにはXSLファイルを入れる。

[5] 出力ファイル

[1],[2]を[3],[4]で実行すると、以下のようなHTMLファイルが出力される。
XSLT実行結果

サンプルプログラム

上記サンプルの一式はこちら。
Download [24KB]

XSLT変換