Entry

libxslt チュートリアル(和訳)

2005年01月23日

なんとなく思い立って,libxslt のチュートリアルを和訳してみました。原文は,「libxslt Tutorial」です。ライセンスは,下記の通り GNU Free Documentation License なので,それに従いますです。

とりあえず訳した程度なので,我ながら,誤訳だか意訳だかよく分からないところもあったりします。誤訳等の指摘がありましたら,どうぞメールでお知らせください。

変更履歴
  • 2005-01-23:初出

John Fleck

This is version 0.4 of the libxslt Tutorial

Copyright © 2001 John Fleck

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license can be found here.

目次

イントロダクション
はじめの関数
解析の準備
スタイルシートの解析する
入力ファイルの解析する
スタイルシートを適用する
結果を保存する
パラメータ(Parameters)
後始末
A ソースコード

概要

libxslt ライブラリを使ったアプリケーションを作るチュートリアルです。libxslt 使うと,XML ファイルを HTML に XSLT 変換することができます。

イントロダクション

Extensible Markup Language (XML)は,構造化されたテキスト形式のデータをやりとりするために作られた,World Wide Web Consortium の標準規格です。XML があちこちで使われるようになったのは,その汎用性(一般性)からです。どんなコンピュータでも,テキストファイルは読むことができます。ということは,適切なツールを使えば,どんなコンピュータでも XML を読むことができるというわけです。

XML のツールの中で,最も重要なモノの1つが XSLT: Extensible Stylesheet Language Transformations です。XSLT は,スタイルシートを使って, XML を任意のテキストに変換することができる宣言型の言語です。libxslt はこの変換を実行するための関数を提供しています。

libxslt は Daniel Veillard が GNOME project のために書いた,フリーの C 言語ライブラリです。これを使って,XSLT 変換を実行するプログラムを書くことができます。

Note
libxslt は,GNOME project の一環として書かれましたが,GNOME ライブラリに依存しているわけではありません。GNOME プロジェクトのライブラリは,ここでの実例で扱いません。

このチュートリアルでは,XML ファイルを読んで,スタイルシートを適用し,その結果を保存するといった,簡単なプログラムを説明します。恐らくこれは,読者が自分で作ろうと思う程のプログラムではないかもしれません。libxslt のパッケージに同梱してある xsltproc を使えば同じことができるし,こっちの方がよっぽど堅牢で libxslt の機能を使い切っているからです。このチュートリアルで示しているプログラムは,libxslt の機能を説明するために設計したもので,xsltproc の機能縮小版(stripped-down version)です。

完全版 xsltproc のソースコードは,libxslt の配布物に同梱してある xsltproc.c です。これは,ウェブからも入手できます(訳注:原文中「ウェブ」にあったリンクは切れていました)。

参照:

はじめの関数

目次

解析の準備
スタイルシートを解析する
入力ファイルを解析する
スタイルシートを適用する
結果を保存する
パラメータ(Parameters)
後始末

XML ファイルを変換するには,3つの関数を実行しなくてはいけません。すなわち,

  1. 入力ファイルを解析する
  2. スタイルシートを解析する
  3. スタイルシートを適用する

ということです。

解析の準備

入力ファイルやスタイルシートを解析する前に,エンティティのハンドリングをセットアップするために,いくつかの手順を踏む必要があります。この手順は,libxslt に特有のものではなくて,XML ファイルを解析する libxml2 プログラムだったら,どんなものでも同じような手順を踏む必要があります。

まず,libxml の中で行われるイロイロ(housekeeping)を,セットアップします。xmlSubstituteEntitiesDefault に int 1 を渡しましょう。こうすると,libxml2 パーサがファイルをパースするときに,エンティティを置換します。(逆に 0 を渡すと,libxml2 はエンティティを置換しません。)

次に,xmlLoadExtDtdDefaultValue に,1 をセットしましょう。これで,libxml に外部エンティティを読み込むように伝えます。もしこれをやらないと,入力ファイルが外部サブセットを通じてエンティティを埋め込んでいるときに,エラーが出ます。

スタイルシートを解析する

スタイルシートを解析するには,1つの関数を呼びます。これは,xmlChar 型の変数を取ります。

    cur = xsltParseStylesheetFile((const xmlChar *)argv[i]);

ここでは,コマンド引数で渡されたスタイルシートのファイル名を xmlChar 型にキャストしました。返ってくる値は,xsltStylesheetPtr です。これは,スタイルシートの構文木と,それに関する他の情報が収まっているメモリ上の構造体です。この値は直接操作することができるけれど,ここでの例でそこまでする必要はありません。

入力ファイルを解析する

スタイルシートを解析するのにも,1つの関数を呼びます。

    doc = xmlParseFile(argv[i]);

返値は xmlDocPtr です。これは,文書の構文木が収まっているメモリ上の構造体です。この値も直接操作することができるけれど,ここでの例でそこまでする必要はありません。

スタイルシートを適用する

これで,XML 文書の構文木とスタイルシートの構文木を,メモリ上に準備できました。スタイルシートを適用する関数は,xsltApplyStylesheetで,以下のように使います。

    res = xsltApplyStylesheet(cur, doc, params);

この関数は,さっき使った2つの関数が返した値,すなわち xsltStylesheetPtr と xmlDocPtr を取ります。3番目の引数である params を指定すると,XSTL のパラメータをスタイルシートに渡すことができます。params は,const char の名前と値を組み合わせた,NULL 終端(NULL-terminated)の配列です。

結果を保存する

libxslt は,出力結果を保存するための関数群を持っています。ここでは,xsltSaveResultToFile を使って,標準出力(stdout)に吐いています。

    xsltSaveResultToFile(stdout, res, cur);
Note
libxml にも xmlSaveFile のような出力用の関数が用意されていて,これを使うこともできます。けれど,エンコーディングの宣言のように,スタイルシートに関係する情報が含まれている場合,libxslt の保存用関数を使わないと,この情報は失われてしまいます。

パラメータ(Parameters)

XSLT では,スタイルシートに付加情報を渡す際に,パラメータを使うことができます。libxslt では,xsltApplyStylesheet に渡す値の1つとして,XSLT パラメータを受け付けます。

チュートリアルの例や,これが元にしている xsltproc では,渡すべきパラメータを,キーと値の組み合わせという形(key-value pairs)で取ります。プログラムは,この組み合わせをコマンド引数から集めて,params 配列に収め,それから関数に渡しています。配列の最後の要素には,NULL がセットされます。

Note
XSLT ノードではなくて,文字列のパラメータを渡すときは,エスケープしなくてはいけません。このチュートリアルで作るプログラムの場合は,次のようにします。tutorial]$ ./libxslt_tutorial --param rootid "'asect1'" stylesheet.xsl filename.xml

後始末

全部終わったら,libxslt と libxml はメモリを解放する関数を用意しています。

    xsltFreeStylesheet(cur); /* (1) */
    xmlFreeDoc(res);         /* (2) */
    xmlFreeDoc(doc);         /* (3) */
    xsltCleanupGlobals();    /* (4) */
    xmlCleanupParser();      /* (5) */
(1) スタイルシートに使ったメモリを解放する。
(2) 出力結果に使ったメモリを解放する。
(3) 元の XML 文書に使ったメモリを解放する。
(4) libxslt が使ったグローバル変数を解放する。
(5) XML パーサが使ったメモリを解放する。

A. ソースコード

libxslt_tutorial.c

/*
 * libxslt_tutorial.c: demo program for the XSL Transformation 1.0 engine
 *
 * based on xsltproc.c, by Daniel.Veillard@imag.fr
 * by John Fleck 
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc.,  59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
 *
 */ 

#include <string.h>
#include <libxml/xmlmemory.h>
#include <libxml/debugXML.h>
#include <libxml/HTMLtree.h>
#include <libxml/xmlIO.h>
#include <libxml/DOCBparser.h>
#include <libxml/xinclude.h>
#include <libxml/catalog.h>
#include <libxslt/xslt.h>
#include <libxslt/xsltInternals.h>
#include <libxslt/transform.h>
#include <libxslt/xsltutils.h>



extern int xmlLoadExtDtdDefaultValue;

static void usage(const char *name) {
    printf("Usage: %s [options] stylesheet file [file ...]\n", name);
    printf("      --param name value : pass a (parameter,value) pair\n");

}

int
main(int argc, char **argv) {
	int i;
	const char *params[16 + 1];
	int nbparams = 0;
	xsltStylesheetPtr cur = NULL;
	xmlDocPtr doc, res;

	if (argc <= 1) {
		usage(argv[0]);
		return(1);
	}
	

 for (i = 1; i < argc; i++) {
        if (argv[i][0] != '-')
            break;
	if ((!strcmp(argv[i], "-param")) ||
                   (!strcmp(argv[i], "--param"))) {
		i++;
		params[nbparams++] = argv[i++];
		params[nbparams++] = argv[i];
		if (nbparams >= 16) {
			fprintf(stderr, "too many params\n");
			return (1);
		}
        }  else {
            fprintf(stderr, "Unknown option %s\n", argv[i]);
            usage(argv[0]);
            return (1);
        }
    }

	params[nbparams] = NULL;
	xmlSubstituteEntitiesDefault(1);
	xmlLoadExtDtdDefaultValue = 1;
	cur = xsltParseStylesheetFile((const xmlChar *)argv[i]);
	i++;
	doc = xmlParseFile(argv[i]);
	res = xsltApplyStylesheet(cur, doc, params);
	xsltSaveResultToFile(stdout, res, cur);

	xsltFreeStylesheet(cur);
	xmlFreeDoc(res);
	xmlFreeDoc(doc);

        xsltCleanupGlobals();
        xmlCleanupParser();
	return(0);

}
Trackback
Trackback URL:
Ads
About
Search This Site
Ads
Categories
Recent Entries
Log Archive
Syndicate This Site
Info.
クリエイティブ・コモンズ・ライセンス
Movable Type 3.36
Valid XHTML 1.1!
Valid CSS!
ブログタイムズ

© 2003-2012 AIAN