Webサービスを開発していると、XML(Extensible Markup Language)形式のデータを扱うことがよくあります。
でも、こんな問題に直面したことはありませんか?
- APIから受け取ったXMLを、HTMLに変換して表示したい
 - XML形式のデータを、別の構造のXMLに変換したい
 - 複数のXMLファイルを統合して、レポートを作成したい
 - XMLをテキストやCSVに変換したい
 
そんなときに活躍するのがXSLT(Extensible Stylesheet Language Transformations)です。
XSLTは、XMLデータを別の形式に変換するための強力な言語です。プログラミングをしなくても、変換ルールを書くだけでデータを自在に変換できます。
この記事では、XSLT変換の仕組みや使い方について、初心者の方にも分かるように詳しく解説していきます。
XSLTとは?基礎知識

XSLTの定義
XSLT(Extensible Stylesheet Language Transformations)は、XML文書を別の形式に変換するための言語です。
特徴:
- XML自体もXMLで書かれている
 - 宣言的な記述(「何をするか」を書く)
 - W3C(World Wide Web Consortium)の標準規格
 
開発の歴史:
- 1999年:XSLT 1.0 リリース
 - 2007年:XSLT 2.0 リリース(大幅に機能強化)
 - 2017年:XSLT 3.0 リリース(最新版)
 
XSLTで何ができる?
変換の例:
1. XML → HTML(Webページ表示)
商品データ(XML) → 商品一覧ページ(HTML)
2. XML → XML(データ構造の変換)
旧形式のXML → 新形式のXML
3. XML → テキスト(レポート生成)
売上データ(XML) → 売上レポート(テキスト)
4. XML → CSV/JSON など
データベースのXML → CSVファイル
XSLTの構成要素
XSLTによる変換には、3つの要素が必要です。
1. ソースXML(入力)
変換元のXMLデータ
2. XSLTスタイルシート(変換ルール)
どう変換するかを記述したファイル
3. 結果ドキュメント(出力)
変換後のデータ
ソースXML → [XSLTプロセッサ + XSLTスタイルシート] → 結果ドキュメント
料理に例えると
XSLTを料理に例えてみましょう。
ソースXML:
- 材料(野菜、肉、調味料など)
 
XSLTスタイルシート:
- レシピ(調理手順)
 
XSLTプロセッサ:
- 料理人
 
結果ドキュメント:
- 完成した料理
 
同じ材料(XML)でも、レシピ(XSLT)を変えれば、違う料理(結果)が作れるんです!
XSLTの基本構造
実際のXSLTスタイルシートを見てみましょう。
最小限のXSLTスタイルシート
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- ここに変換ルールを書く -->
</xsl:stylesheet>
重要な部分:
1. XML宣言
<?xml version="1.0" encoding="UTF-8"?>
XSLT自体もXMLファイルなので、XML宣言が必要です。
2. ルート要素
<xsl:stylesheet version="1.0" xmlns:xsl="...">
xsl:stylesheetまたはxsl:transformを使用version属性でXSLTのバージョンを指定xmlns:xslで名前空間を宣言
テンプレートの基本
XSLTの変換ルールは、テンプレートとして記述します。
<xsl:template match="パターン">
    <!-- 変換内容 -->
</xsl:template>
match属性:
どのXML要素に対して適用するかを指定します(XPathで指定)。
例:ルート要素にマッチ
<xsl:template match="/">
    <!-- ドキュメント全体の処理 -->
</xsl:template>
簡単な例:XMLをHTMLに変換
実際に動く例を見てみましょう。
ソースXML
書籍データのXMLです。
books.xml:
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
    <book id="001">
        <title>プログラミング入門</title>
        <author>山田太郎</author>
        <price>2500</price>
        <year>2024</year>
    </book>
    <book id="002">
        <title>データベース設計</title>
        <author>佐藤花子</author>
        <price>3200</price>
        <year>2023</year>
    </book>
    <book id="003">
        <title>Web開発の基礎</title>
        <author>鈴木一郎</author>
        <price>2800</price>
        <year>2024</year>
    </book>
</bookstore>
XSLTスタイルシート
このXMLをHTMLテーブルに変換します。
books_to_html.xsl:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- ルートテンプレート -->
    <xsl:template match="/">
        <html>
            <head>
                <title>書籍一覧</title>
                <style>
                    table { border-collapse: collapse; width: 100%; }
                    th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
                    th { background-color: #4CAF50; color: white; }
                    tr:nth-child(even) { background-color: #f2f2f2; }
                </style>
            </head>
            <body>
                <h1>書籍一覧</h1>
                <table>
                    <tr>
                        <th>ID</th>
                        <th>タイトル</th>
                        <th>著者</th>
                        <th>価格</th>
                        <th>発行年</th>
                    </tr>
                    <!-- 各book要素を処理 -->
                    <xsl:apply-templates select="bookstore/book"/>
                </table>
            </body>
        </html>
    </xsl:template>
    <!-- book要素のテンプレート -->
    <xsl:template match="book">
        <tr>
            <td><xsl:value-of select="@id"/></td>
            <td><xsl:value-of select="title"/></td>
            <td><xsl:value-of select="author"/></td>
            <td><xsl:value-of select="price"/>円</td>
            <td><xsl:value-of select="year"/></td>
        </tr>
    </xsl:template>
</xsl:stylesheet>
変換結果
上記のXSLTを適用すると、以下のようなHTMLが生成されます。
result.html:
<html>
    <head>
        <title>書籍一覧</title>
        <style>
            table { border-collapse: collapse; width: 100%; }
            th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
            th { background-color: #4CAF50; color: white; }
            tr:nth-child(even) { background-color: #f2f2f2; }
        </style>
    </head>
    <body>
        <h1>書籍一覧</h1>
        <table>
            <tr>
                <th>ID</th>
                <th>タイトル</th>
                <th>著者</th>
                <th>価格</th>
                <th>発行年</th>
            </tr>
            <tr>
                <td>001</td>
                <td>プログラミング入門</td>
                <td>山田太郎</td>
                <td>2500円</td>
                <td>2024</td>
            </tr>
            <tr>
                <td>002</td>
                <td>データベース設計</td>
                <td>佐藤花子</td>
                <td>3200円</td>
                <td>2023</td>
            </tr>
            <tr>
                <td>003</td>
                <td>Web開発の基礎</td>
                <td>鈴木一郎</td>
                <td>2800円</td>
                <td>2024</td>
            </tr>
        </table>
    </body>
</html>
このHTMLをブラウザで開けば、見やすい表形式で書籍情報が表示されます。
XPath:XMLの場所を指定する
XSLTでは、XPath(XML Path Language)を使ってXML内の要素を指定します。
XPathとは?
XPathは、XML文書内の要素や属性をパスで指定する言語です。
ファイルシステムのパスに似ている:
Windows: C:\Users\Document\file.txt
XPath:   /bookstore/book/title
基本的なXPath表現
1. 絶対パス
/bookstore/book/title
ルートから要素までの完全なパス
2. 相対パス
book/title
現在位置からの相対的なパス
3. すべての子要素
//book
どこにあっても、すべての<book>要素
4. 属性
@id
属性を指定(@記号を使う)
5. 述語(条件指定)
book[@id='001']
id属性が001のbook要素
book[price > 3000]
priceが3000より大きいbook要素
6. 位置指定
book[1]
最初のbook要素(1から始まる)
book[last()]
最後のbook要素
XPath軸
より高度な指定方法です。
ancestor::book
先祖要素
parent::bookstore
親要素
child::title
子要素
descendant::author
子孫要素
following-sibling::book
後続の兄弟要素
preceding-sibling::book
先行の兄弟要素
XPath関数
便利な関数が用意されています。
文字列関数:
concat(author, ' - ', title)
文字列の連結
substring(title, 1, 5)
部分文字列
string-length(title)
文字列の長さ
contains(title, 'プログラミング')
文字列を含むかチェック
数値関数:
sum(book/price)
合計
count(book)
要素の数
round(price)
四捨五入
XSLT要素:変換の道具箱
XSLTでよく使う要素を見ていきましょう。
xsl:value-of(値の取得)
要素や属性の値を取得します。
<xsl:value-of select="XPath式"/>
例:
<!-- 要素の値 -->
<xsl:value-of select="title"/>
<!-- 属性の値 -->
<xsl:value-of select="@id"/>
<!-- 計算結果 -->
<xsl:value-of select="price * 1.1"/>
xsl:apply-templates(テンプレートの適用)
指定した要素に対してテンプレートを適用します。
<xsl:apply-templates select="XPath式"/>
例:
<!-- すべてのbook要素を処理 -->
<xsl:apply-templates select="book"/>
<!-- 条件に合う要素だけ処理 -->
<xsl:apply-templates select="book[price > 3000]"/>
xsl:for-each(繰り返し)
要素を繰り返し処理します。
<xsl:for-each select="XPath式">
    <!-- 繰り返す内容 -->
</xsl:for-each>
例:
<ul>
    <xsl:for-each select="book">
        <li>
            <xsl:value-of select="title"/> - 
            <xsl:value-of select="author"/>
        </li>
    </xsl:for-each>
</ul>
出力:
<ul>
    <li>プログラミング入門 - 山田太郎</li>
    <li>データベース設計 - 佐藤花子</li>
    <li>Web開発の基礎 - 鈴木一郎</li>
</ul>
xsl:if(条件分岐)
条件に応じて処理を実行します。
<xsl:if test="条件式">
    <!-- 条件が真の場合の処理 -->
</xsl:if>
例:
<xsl:for-each select="book">
    <xsl:if test="price > 3000">
        <p class="expensive">
            <xsl:value-of select="title"/> は高額です
        </p>
    </xsl:if>
</xsl:for-each>
注意:xsl:ifにはelseがありません。複数分岐にはxsl:chooseを使います。
xsl:choose(複数分岐)
複数の条件を扱います(switch文のようなもの)。
<xsl:choose>
    <xsl:when test="条件1">
        <!-- 条件1が真の場合 -->
    </xsl:when>
    <xsl:when test="条件2">
        <!-- 条件2が真の場合 -->
    </xsl:when>
    <xsl:otherwise>
        <!-- どの条件も満たさない場合 -->
    </xsl:otherwise>
</xsl:choose>
例:価格による分類
<xsl:for-each select="book">
    <tr>
        <td><xsl:value-of select="title"/></td>
        <td>
            <xsl:choose>
                <xsl:when test="price < 2000">
                    <span style="color: green;">格安</span>
                </xsl:when>
                <xsl:when test="price < 3000">
                    <span style="color: blue;">標準</span>
                </xsl:when>
                <xsl:otherwise>
                    <span style="color: red;">高額</span>
                </xsl:otherwise>
            </xsl:choose>
        </td>
    </tr>
</xsl:for-each>
xsl:sort(並べ替え)
要素をソートします。
<xsl:sort select="ソート対象" order="asc|desc" data-type="text|number"/>
例:価格の安い順
<xsl:for-each select="book">
    <xsl:sort select="price" data-type="number" order="ascending"/>
    <tr>
        <td><xsl:value-of select="title"/></td>
        <td><xsl:value-of select="price"/></td>
    </tr>
</xsl:for-each>
例:タイトルのアルファベット順
<xsl:for-each select="book">
    <xsl:sort select="title" data-type="text" order="ascending"/>
    <li><xsl:value-of select="title"/></li>
</xsl:for-each>
xsl:attribute(属性の追加)
動的に属性を追加します。
<xsl:attribute name="属性名">値</xsl:attribute>
例:
<a>
    <xsl:attribute name="href">
        <xsl:value-of select="url"/>
    </xsl:attribute>
    <xsl:attribute name="target">_blank</xsl:attribute>
    <xsl:value-of select="title"/>
</a>
出力:
<a href="http://example.com" target="_blank">プログラミング入門</a>
xsl:element(要素の作成)
動的に要素を作成します。
<xsl:element name="要素名">
    <!-- 要素の内容 -->
</xsl:element>
例:
<xsl:element name="h{$level}">
    <xsl:value-of select="title"/>
</xsl:element>
$levelが2なら<h2>タイトル</h2>が生成されます。
xsl:variable(変数)
値を変数に保存します。
<xsl:variable name="変数名" select="値"/>
例:
<xsl:variable name="tax" select="1.1"/>
<xsl:variable name="totalPrice" select="price * $tax"/>
<p>
    価格: <xsl:value-of select="price"/>円
    (税込: <xsl:value-of select="$totalPrice"/>円)
</p>
注意:
変数は一度設定したら変更できません(不変)。
xsl:copy / xsl:copy-of(コピー)
xsl:copy(現在のノードをコピー):
<xsl:copy>
    <!-- 子要素や属性は含まれない -->
</xsl:copy>
xsl:copy-of(要素全体をコピー):
<xsl:copy-of select="XPath式"/>
例:要素の複製
<!-- 元の構造を保持したままコピー -->
<xsl:copy-of select="book"/>
実践例:様々な変換パターン
実際によく使われる変換パターンを見てみましょう。
例1:条件付きフィルタリング
シナリオ:
2024年に発行された書籍だけを表示
XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <html>
            <head>
                <title>2024年の新刊</title>
            </head>
            <body>
                <h1>2024年の新刊</h1>
                <ul>
                    <xsl:for-each select="bookstore/book[year=2024]">
                        <li>
                            <strong><xsl:value-of select="title"/></strong>
                            (著者: <xsl:value-of select="author"/>)
                        </li>
                    </xsl:for-each>
                </ul>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>
例2:集計と統計
シナリオ:
書籍の合計金額と平均価格を計算
XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <html>
            <head>
                <title>書籍統計</title>
            </head>
            <body>
                <h1>書籍統計</h1>
                <xsl:variable name="totalBooks" select="count(bookstore/book)"/>
                <xsl:variable name="totalPrice" select="sum(bookstore/book/price)"/>
                <xsl:variable name="avgPrice" select="$totalPrice div $totalBooks"/>
                <table border="1">
                    <tr>
                        <th>項目</th>
                        <th>値</th>
                    </tr>
                    <tr>
                        <td>書籍数</td>
                        <td><xsl:value-of select="$totalBooks"/>冊</td>
                    </tr>
                    <tr>
                        <td>合計金額</td>
                        <td><xsl:value-of select="$totalPrice"/>円</td>
                    </tr>
                    <tr>
                        <td>平均価格</td>
                        <td><xsl:value-of select="format-number($avgPrice, '#,##0')"/>円</td>
                    </tr>
                </table>
                <h2>最高額の書籍</h2>
                <xsl:for-each select="bookstore/book">
                    <xsl:sort select="price" data-type="number" order="descending"/>
                    <xsl:if test="position() = 1">
                        <p>
                            <strong><xsl:value-of select="title"/></strong><br/>
                            価格: <xsl:value-of select="price"/>円
                        </p>
                    </xsl:if>
                </xsl:for-each>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>
例3:グループ化(Muenchian Method)
シナリオ:
著者ごとに書籍をグループ化
拡張されたXML:
<bookstore>
    <book><author>山田太郎</author><title>プログラミング入門</title></book>
    <book><author>山田太郎</author><title>上級プログラミング</title></book>
    <book><author>佐藤花子</author><title>データベース設計</title></book>
</bookstore>
XSLT(XSLT 1.0でのグループ化):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- キーの定義(著者名でインデックス) -->
    <xsl:key name="books-by-author" match="book" use="author"/>
    <xsl:template match="/">
        <html>
            <head>
                <title>著者別書籍一覧</title>
            </head>
            <body>
                <h1>著者別書籍一覧</h1>
                <!-- ユニークな著者を取得 -->
                <xsl:for-each select="bookstore/book[generate-id() = generate-id(key('books-by-author', author)[1])]">
                    <h2><xsl:value-of select="author"/></h2>
                    <ul>
                        <!-- 同じ著者の書籍を列挙 -->
                        <xsl:for-each select="key('books-by-author', author)">
                            <li><xsl:value-of select="title"/></li>
                        </xsl:for-each>
                    </ul>
                </xsl:for-each>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>
例4:XMLからCSV形式への変換
シナリオ:
XMLデータをCSV形式のテキストに変換
XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" encoding="UTF-8"/>
    <xsl:template match="/">
        <!-- ヘッダー行 -->
        <xsl:text>ID,タイトル,著者,価格,年
</xsl:text>
        <!-- データ行 -->
        <xsl:for-each select="bookstore/book">
            <xsl:value-of select="@id"/>
            <xsl:text>,</xsl:text>
            <xsl:value-of select="title"/>
            <xsl:text>,</xsl:text>
            <xsl:value-of select="author"/>
            <xsl:text>,</xsl:text>
            <xsl:value-of select="price"/>
            <xsl:text>,</xsl:text>
            <xsl:value-of select="year"/>
            <xsl:text>
</xsl:text><!-- 改行 -->
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>
出力(CSV):
ID,タイトル,著者,価格,年
001,プログラミング入門,山田太郎,2500,2024
002,データベース設計,佐藤花子,3200,2023
003,Web開発の基礎,鈴木一郎,2800,2024
例5:XML構造の変換
シナリオ:
旧形式のXMLを新形式に変換
旧形式XML:
<products>
    <product code="P001" name="ノートPC" price="120000"/>
    <product code="P002" name="マウス" price="2000"/>
</products>
新形式に変換(要素ベース):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" encoding="UTF-8"/>
    <xsl:template match="/">
        <catalog>
            <xsl:apply-templates select="products/product"/>
        </catalog>
    </xsl:template>
    <xsl:template match="product">
        <item>
            <id><xsl:value-of select="@code"/></id>
            <name><xsl:value-of select="@name"/></name>
            <price currency="JPY">
                <xsl:value-of select="@price"/>
            </price>
        </item>
    </xsl:template>
</xsl:stylesheet>
出力(新形式XML):
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
    <item>
        <id>P001</id>
        <name>ノートPC</name>
        <price currency="JPY">120000</price>
    </item>
    <item>
        <id>P002</id>
        <name>マウス</name>
        <price currency="JPY">2000</price>
    </item>
</catalog>
XSLT変換の実行方法
XSLTスタイルシートを実際に実行する方法を見てみましょう。
ブラウザでの実行
XMLファイルにスタイルシート参照を追加
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="books_to_html.xsl"?>
<bookstore>
    <!-- ... -->
</bookstore>
2行目の<?xml-stylesheet ... ?>を追加して、このXMLファイルをブラウザで開くだけです。
メリット:
- 簡単
 - サーバー不要
 
デメリット:
- 古いブラウザでは動作しないことがある
 - セキュリティ制限がある場合がある
 
コマンドラインツール
xsltproc(Linux/Mac):
xsltproc books_to_html.xsl books.xml > result.html
Saxon(Java):
java -jar saxon.jar -s:books.xml -xsl:books_to_html.xsl -o:result.html
Xalan(Java):
java org.apache.xalan.xslt.Process -IN books.xml -XSL books_to_html.xsl -OUT result.html
プログラムからの実行
Java(JAXP):
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import java.io.File;
public class XSLTTransformer {
    public static void main(String[] args) {
        try {
            // TransformerFactoryを作成
            TransformerFactory factory = TransformerFactory.newInstance();
            // XSLTスタイルシートを読み込む
            Source xslt = new StreamSource(new File("books_to_html.xsl"));
            Transformer transformer = factory.newTransformer(xslt);
            // ソースXMLを読み込む
            Source xml = new StreamSource(new File("books.xml"));
            // 結果を出力
            Result result = new StreamResult(new File("result.html"));
            // 変換を実行
            transformer.transform(xml, result);
            System.out.println("変換が完了しました");
        } catch (TransformerException e) {
            e.printStackTrace();
        }
    }
}
Python(lxml):
from lxml import etree
# XMLファイルを読み込む
xml_doc = etree.parse("books.xml")
# XSLTスタイルシートを読み込む
xslt_doc = etree.parse("books_to_html.xsl")
transform = etree.XSLT(xslt_doc)
# 変換を実行
result = transform(xml_doc)
# 結果を保存
with open("result.html", "wb") as f:
    f.write(etree.tostring(result, pretty_print=True, encoding="UTF-8"))
print("変換が完了しました")
JavaScript/Node.js(xslt3):
const SaxonJS = require('saxon-js');
const result = SaxonJS.transform({
    stylesheetFileName: "books_to_html.sef.json",  // コンパイル済みスタイルシート
    sourceFileName: "books.xml",
    destination: "file",
    resultFileName: "result.html"
});
console.log("変換が完了しました");
C#(.NET):
using System;
using System.Xml;
using System.Xml.Xsl;
class XSLTTransformer
{
    static void Main()
    {
        try
        {
            // XSLTを読み込む
            XslCompiledTransform xslt = new XslCompiledTransform();
            xslt.Load("books_to_html.xsl");
            // 変換を実行
            xslt.Transform("books.xml", "result.html");
            Console.WriteLine("変換が完了しました");
        }
        catch (Exception e)
        {
            Console.WriteLine($"エラー: {e.Message}");
        }
    }
}
オンラインツール
ブラウザで試せるツール:
- XSLT Fiddle:https://xsltfiddle.liberty-development.net/
 - FreeFormatter.com:https://www.freeformatter.com/xsl-transformer.html
 - Code Beautify:https://codebeautify.org/xsltviewer
 
XMLとXSLTを貼り付けるだけで、すぐに結果が見られます。
XSLT 2.0/3.0の新機能
XSLT 1.0の制約を超えた、より強力な機能です。
XSLT 2.0の主な機能
1. xsl:for-each-group(グループ化)
<xsl:for-each-group select="book" group-by="author">
    <h2><xsl:value-of select="current-grouping-key()"/></h2>
    <ul>
        <xsl:for-each select="current-group()">
            <li><xsl:value-of select="title"/></li>
        </xsl:for-each>
    </ul>
</xsl:for-each-group>
2. 正規表現のサポート
<xsl:if test="matches(email, '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$')">
    <p>有効なメールアドレス</p>
</xsl:if>
3. 日付と時刻の処理
<xsl:value-of select="current-date()"/>
<xsl:value-of select="format-date(current-date(), '[D01]/[M01]/[Y0001]')"/>
4. 複数の出力ファイル
<xsl:result-document href="output_{position()}.html">
    <!-- 複数ファイルに分割して出力 -->
</xsl:result-document>
XSLT 3.0の主な機能
1. ストリーミング処理
巨大なXMLファイルを効率的に処理できます。
<xsl:mode streamable="yes"/>
2. パッケージとモジュール化
<xsl:package name="myPackage" package-version="1.0">
    <!-- 再利用可能なテンプレート -->
</xsl:package>
3. マップとアレイ
<xsl:variable name="map" as="map(*)">
    <xsl:map>
        <xsl:map-entry key="'name'" select="'John'"/>
        <xsl:map-entry key="'age'" select="30"/>
    </xsl:map>
</xsl:variable>
トラブルシューティング
XSLTでよくある問題と解決策です。
問題1:変換結果が空
症状:
変換しても何も出力されない
原因:
- XPathが間違っている
 - 名前空間の問題
 - テンプレートがマッチしていない
 
解決策:
1. XPathを確認
<!-- デバッグ出力 -->
<xsl:template match="/">
    <p>書籍数: <xsl:value-of select="count(bookstore/book)"/></p>
    <p>パス確認: <xsl:value-of select="name(*)"/></p>
</xsl:template>
2. 名前空間を確認
XMLに名前空間がある場合:
<bookstore xmlns="http://example.com/books">
    ...
</bookstore>
XSLTでも名前空間を宣言:
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:b="http://example.com/books">
    <xsl:template match="b:bookstore">
        <xsl:for-each select="b:book">
            ...
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>
問題2:HTMLエンティティが正しく表示されない
症状:<、>などがそのまま表示される
解決策:
<xsl:output 
    method="html" 
    encoding="UTF-8" 
    indent="yes"
    doctype-public="-//W3C//DTD HTML 4.01//EN"
    doctype-system="http://www.w3.org/TR/html4/strict.dtd"/>
問題3:特殊文字が正しく処理されない
症状:<、>、&などの特殊文字で変換が失敗
解決策:
XMLでエスケープ:
<!-- XMLでの記述 -->
<  →  <
>  →  >
& →  &
" → "
' → '
XSLTでの比較では:
<!-- NG -->
<xsl:if test="price < 3000">
<!-- OK -->
<xsl:if test="price < 3000">
問題4:日本語が文字化けする
症状:
日本語が文字化けする
解決策:
1. XML宣言でUTF-8を指定
<?xml version="1.0" encoding="UTF-8"?>
2. XSLTでもUTF-8を指定
<xsl:output method="html" encoding="UTF-8"/>
3. ファイルを実際にUTF-8で保存
エディタで保存する際、エンコーディングを確認してください。
問題5:変換が遅い
症状:
大きなXMLの変換に時間がかかる
解決策:
1. xsl:keyを使う
繰り返し検索する場合、キーを使うと高速化します。
<xsl:key name="book-by-id" match="book" use="@id"/>
<!-- 通常の検索(遅い) -->
<xsl:value-of select="//book[@id='001']/title"/>
<!-- キーを使った検索(速い) -->
<xsl:value-of select="key('book-by-id', '001')/title"/>
2. XPath式を最適化
<!-- 遅い -->
<xsl:for-each select="//book">
<!-- 速い -->
<xsl:for-each select="bookstore/book">
3. XSLT 3.0のストリーミングを使う
まとめ:XSLTはXML変換の強力なツール
XSLT(Extensible Stylesheet Language Transformations)は、XMLを別の形式に変換するための言語です。
この記事のポイント:
- XSLTの役割:XMLデータを別の形式(HTML、CSV、別のXMLなど)に変換
 - 3つの要素:ソースXML、XSLTスタイルシート、結果ドキュメント
 - テンプレート:
xsl:templateで変換ルールを記述 - XPath:XML内の要素を指定するパス言語
 - 主要な要素:
xsl:value-of、xsl:for-each、xsl:if、xsl:choose、xsl:sortなど - 実用例:HTMLへの変換、フィルタリング、集計、グループ化、構造変換
 - 実行方法:ブラウザ、コマンドライン、プログラムから実行可能
 - バージョン:XSLT 1.0(基本)、2.0/3.0(高機能)
 - トラブルシューティング:名前空間、エンコーディング、パフォーマンス
 
プログラミング言語を使わずに、宣言的に変換ルールを書くだけでデータ変換ができるのがXSLTの魅力です。
最近では、JSONやYAMLなど他のデータ形式が人気ですが、XMLを扱う場面は依然として多く、特にレガシーシステムや公的機関のデータ、SOAPベースのWebサービスなどでXMLは現役です。
XSLTをマスターすれば、XMLデータを自在に加工できるようになります。最初は複雑に感じるかもしれませんが、基本的なパターンを覚えれば、様々な変換に応用できます。
XMLを扱う機会があったら、ぜひXSLTを試してみてください。データ変換が驚くほど簡単になりますよ!
  
  
  
  
              
              
              
              
              

コメント