- XSLTをWebブラウザ上で動作するクライアントサイドのビルドシステムのように使い、XMLデータをHTMLに変換して、静的サイトジェネレーターの複雑さを減らせる
- 一般的な静的サイトは、
.json、.md、.txtのようなデータと、Hugo、Next.js、Astroのようなビルドシステム、そして静的HTML出力で構成されるが、大きなフレームワークは単純なMarkdownブログにも過剰な複雑さを持ち込むことがある
- HTMLとCSSだけを使おうとすると、複数ページのヘッダーやフッターを手作業でコピーする必要があり、HTML importはなく、Web ComponentsにはJavaScriptエンジンが必要という制約がある
- XML文書に
<?xml-stylesheet type="text/xsl" href="blog.xsl"?> を追加し、XSLTテンプレートを書けば、ブラウザがアクセス時点でHTML出力を生成できる
- この方法はJavaScriptなしで静的ファイルとして配布できるが、あらゆるものを置き換える完全な解決策ではなく、Web開発のツールボックスに加えられる別の選択肢である
静的サイトビルドの複雑さ
- 一般的な静的Webサイト制作の流れは、データ、ビルドシステム、静的HTML出力に分かれる
- データは
.json、.md、.txt のようなファイルに保存される
- ビルドシステムの例として Hugo、Next.js、Astro などがある
- 最終成果物は静的HTMLである
- フレームワークを外してシンプルなHTMLとCSSだけを使いたくても、ページ数が増えると共通のヘッダーとフッターを繰り返しコピーしなければならない
- 代替として思い浮かぶ選択肢にもそれぞれ制約がある
- HTML importは存在しない
- Web ComponentsにはJavaScriptが必要で、したがってJavaScriptエンジンも必要になる
ブラウザをビルドシステムとして使う発想
- Webブラウザはすでに
text/html、text/markdown、application/xml のような複数の形式を理解できる
- ブラウザをデータからHTMLを生成するシステムとして使えば、別途ビルドツールなしでWeb標準ベースの流れを作れる
- RSSフィードをもっと見やすく表示しようとする過程で、XSLT をXML文書用スタイルシートとして使えることに気づいた
- XMLはHTMLに似て見えるが、Webデータだけに限定されないデータ表現方式であり、XML spec で確認できる
XMLからHTMLへ変換する方法
- XML文書にはブログ記事のようなデータを格納できる
<?xml version="1.0"?>
<blog>
<post id="42" publishedAt="2025-06-26">
<title>Hello XSLT</title>
<tags>…</tags>
</post>
</blog>
- XML文書にはXSLスタイルシートを関連付ける宣言を追加できる
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="blog.xsl"?>
<blog>
<post id="42" publishedAt="2025-06-26">
<title>Hello XSLT</title>
<tags>…</tags>
</post>
</blog>
- XSLTテンプレートはXML入力を受け取り、HTML構造を出力する
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" />
<xsl:template match="/">
<html>
<head> … </head>
<body> … </body>
</html>
</xsl:template>
</xsl:stylesheet>
- XSLTは
(XML) => HTML の形で捉えられ、ループ、変数、importのようなビルドシステム機能を提供する
- 親XML文書のデータをXSLT側で取り込み、動的に出力できる
<head>
<xsl:value-of select="title" /> | Blog
</head>
実行と配布の方法
- XMLファイルをブラウザで開けば、XSLT変換を実行できる
open blog.xml -a Safari
- すべてのWebブラウザはページアクセス時のXSLT変換をサポートし、変換結果のHTMLを表示する
- この方法は、ユーザーのコンピューター上で実行されるクライアントサイドのビルドシステムのように動作する
- 静的ファイルの配布が容易で、JavaScriptなしで動作する
限界と位置づけ
- ブログデータはJSONではなくXMLで保存する必要があるが、XMLはHTMLのように見え、パースしやすく、柔軟で、Webでネイティブにサポートされている
- XSLT方式は完璧ではなく、あらゆるものを置き換えるわけではない
- 古いWeb標準、仕様、ブラウザ機能を活用して、シンプルな静的Webサイト制作に使える別のツールとなる
1件のコメント
Hacker News のコメント
XML テンプレートに XSLT を多用していた会社で働いたことがあるが、良いものではなく、可能ならおそらく移行していただろう
新しい標準があっても XSLT 1.0 がいまだに支配的で、最新の標準に比べると制約が多く奇妙だった
XSLT テンプレートの性能問題を解くのは地獄に近い。チューリング完全な関数型スタイルの言語なのに性能がかなり抽象化されていて、たいていの文書では問題なく動くテンプレートが、100 行の表ひとつで爆発することもある。調べてみると表処理テンプレートが O(N^2) 以上で、各行ごとに XPath がさらに O(N) 以上かもしれず、最適化方法もはっきりしなかった。記憶では、1 つの文書を XSLT で処理するのに 7 分以上かかっていた
JS にも別の問題はあるだろうが、アルゴリズム計算量の問題を解決できないことはその一つではない
今では key(インデックス) のような機能で処理を大幅に速くできるし、Saxon のような優れた XSLT 実装も性能面で確実に役立つ
XML を別の形式に変換するときはロジックを構造化できるので、XSLT はかなり便利だ
2013 年に XSLT を多用していたが、その時点ですでに 1.0 はどこから見ても完全に死んでいた。Saxon は XSLT 2 用として無料で、素晴らしかった
巨大な文書も小さな文書の大量変換も行ったが、性能問題はまったくなかった
習得すれば数独を解いたような満足感は得られるが、普通は目的達成にはもっと少ない道具で十分なので、ビルドやテンプレートの標準的なアプローチになるのは難しい
そのうえ XML も、誰もが好む形式というわけではない
記憶が正しければ、かなり賢い最適化もしてくれた
かなり無理のある推測かもしれないが、1990〜2000 年代にはブラウザがばらばらだったため、同じ動作を作ろうとして JS を使い始めたのであり、本当に必要だったのは良い CSS スタイルと一貫した動作だった
時間が経つにつれてブラウザは似た動作をするようになったが、すでに全ブラウザでページを同じように見せるフレームワークに慣れてしまい、JSON データをレンダリングするパラダイムへと変わっていた
今の技術水準なら、サーバーが生成する 昔ながらの Web ページ も十分に対応可能で、フットプリントが小さく、より速く、メモリ使用量も少ない
最近レガシーシステムの移行をしていて、2000 年代式の「HTTP リクエストごとに 1 ページ」という構造を見たが、追加・削除のようなすべての操作でリロードが必要でも、React システムよりはるかに速かった。インターネットは高速化し、携帯電話のメモリは JS フレームワークが浪費しており、バックエンドはいまだに CRUD、ページネーション、トランザクションが大半だ
HN のように単純な場所ではページ全体のリロードがよく合うし、JS フレームワークの代わりに単純な Web サイトで十分な例も多い
しかし、全員がページ全体のリロードに戻れるというのは正しくない。実際の Web アプリケーション の中には、全体リロードがひどいユーザー体験になるものがある
概して Web サイト、Web 文書、Web フォームは全体リロードでも可能だが、複雑なものを表示し操作しなければならない Web アプリケーションには向いていない
当時はユーザーエージェント検出や各種 quirks の順序に頼ってレイアウトを合わせていたし、JS がレイアウト関連要素へ簡単にアクセスできたようにも思えない
CSS も一貫性をすぐにもたらしたわけではない。機能が揃った後でも混乱していて、CSS Zen Garden に誰もが感嘆しつつ、実際のコードはテーブルで組んでいた時代だった
フレームワークが「一貫した見た目」に大きな影響を与えたのかも分からない。jQuery から離れる頃には、すでに CSS が見た目を担当していた
ページごとに複数のクエリを投げ、ビュー専用のレスポンス形状を作るために複雑な JOIN も多用する条件での話だ。HTML 文字列に補間する前にデータを適切な形で取得しておくと、10 万行の表のような境界ケースで性能に大きく効く
経験上、HTML テンプレートエンジンとデータベースは近いほどよい。結局、構造化された DOM もクライアントに送るべきバイトストリームにすぎない
StringBuilder と賢い SQL クエリで済むところに精巧な AST/パーサー的アプローチを検討することで、無意味で自己目的化した産業が生まれたのだと思う。反論はたいてい、開発者は HTML エスケープ関数を正しく使えないと見なす、セキュリティ監視者的な態度に行き着いた
2000年代のエンタープライズXMLの肥大ぶりのせいで、この技術が古く見えてしまい、みんながより「すっきりした」JSONへ流れていったのは残念
XSLTとXPathは非常に成熟していて、ほかの形式で今も遭遇する多くの問題をすでに解決してくれていた
昔はPHPのストリームラッパーとXSLT includeを乱用していた、いい思い出もある
古い偏見かもしれないが、ブラウザにローカルで処理させるのはまだ少し不安。昔は互換性の地雷原だったから
XML側のスキーマのようなものはずっと明確に定義されていて、JSON側が追いつくのにほぼ10年かかったように感じる
最後にちゃんと扱ったXML技術はEXIで、XML文書を圧縮されたバイナリデータストリームに変える転送方式だった。データ構造をASCIIに変換して圧縮し、HTTPで送ってまた元に戻すのは少し滑稽だからだ
今はprotobuf系のほうが人気だが、XMLが残り続けていたら、相互に噛み合う互換標準の世界になっていたかもしれない。一方でprotobuf/gRPCとJSON APIの間には堅い壁があるが、もしかするとそのほうが良いのかもしれない
XPathも悪くない。構文を全部覚えるのは難しいが、少し試せばだいたい行きたい場所にたどり着ける
XSLTは完全に狂ったたわごとで、燃えてなくなるべきだ
データに対する比較的安定したローカル変更を可能にする組み合わせとして、XML + XPathはひどく過小評価されている。XMLが「旧式」という評判のせいか、ほかのゲームではあまり見ないが、この用途には非常に堅牢なシステムだ
https://rimworldwiki.com/wiki/Modding_Tutorials/PatchOperati...
しかしWebブームが大きくなると、W3CとMSがSOAPやWS-*のようなものを作り、XSLTを含むXMLベースのプログラミング言語もいくつも生まれた
HNの人たちには言ってはいけないが、XSLTはもともとSchemeだったのに必ずXMLでなければならず、JavaScriptがJavaの名前を借りなければならなかったのと同じ狂気の時代だった
最近はフィードを装飾するのにXSLTを使っている
たとえば https://susam.net/feed.xml と https://susam.net/feed.xsl だ
19歳でプロのソフトウェアエンジニアとして最初に担当したプロジェクトの1つが、会社が購入したGoogle Search Appliance 2台をカスタマイズする仕事だった
会社は巨大なCIFS文書リポジトリを全文検索できれば事業開発プロセスが改善すると見込み、CentOSとGoogle流のPythonが載った黄色い前面のDellサーバーラックに数十万ドルを費やした
2011年ごろはXHTMLが流行しており、GSAはバックエンドでXMLとして提供した検索結果をXSLTでXHTMLに変換する仕組みだった
基本テンプレートを取り、レンダリングされたColdFusionアプリケーションページ、StackOverflow、W3Schoolsのチュートリアルから盗んだアセットとマークアップで、会社のイントラネットポータルのような怪物を作った
その後LinkedInで複数のDoD請負企業から「XMLの専門性」を見て文書近代化プロジェクトに参加しないかと連絡が来るようになり、この経験は履歴書から外すべきだとすぐに学んだ
JSONレスポンスからデシリアライズしたTypeScriptインターフェースの配列をJSXで反復しながらため息をつくときは、XSLTで同じことをしていた自分を思い出せばいい
XMLは冗長だと文句を言う人が多く、遠目には複雑に見えるが、XMLベースで良いファイル形式を作り、DTDで検証し、必要ならXSLTで人間に読みやすく整形できる点が良い
XMLはテキストベースのファイル形式におけるC++のようなものだ。成熟していて、バッテリー同梱で、強力で、望めばどんな言語からでも使える
古く成熟した言語がそれぞれの奇妙さのために叩かれるのと同じように、XMLを叩くのも流行になってしまった。用途に合わなければ使わなければいいが、怪物扱いするものではない
2000年代初頭にXMLとXSLTがどこまで進んでいたかを示す例として、以前働いていた会社はXMLをワイヤスピードでパースし、XSLTをチップ上でネイティブに処理するASICを作っていた
インターネットの未来はすべてXML/XSLTになると予想していたからだ。Intelがその会社を買収し、内部技術はSSEアクセラレータに入った
「XSLT がブラウザでネイティブに動く」という魔法が何なのか驚き
最後に XSLT を使ったのは20年ほど前ですが、当時は数年間かなり多用していました。その頃は動かすのに巨大で不安定なエンタープライズ Java の塔が必要で、XSLT 自体の優雅さを損なっていました
でも XSLT が実際にブラウザで動くなら、どこでもホスティングできる静的テンプレートという聖杯が、ずっと目の前にあったということになります
むしろ v3 対応が入れば、ネイティブなテンプレート対応として静的 Web ページを提供しやすくなりそうです
CMS は埋め込み HTML を含む XML ファイルを吐き出し、キャッシュが非常によく効きました。パーソナライズと HTML/JS レンダリングは、サーバー側でキャッシュプロキシと組み合わせて処理していました
XSL 変換はキャッシュの後ろで実行され、多くのトラフィックに追従できるほど高速でした。ここでの XML の目的は、用意済みの HTML は blob として入れ、パーソナライズが必要な部分だけを XML タグとして残すことでした
最終変換はかなり速く、肝は XSL 変換器の出力をメモリ上のバッファ全体に溜めず、レスポンスの出力ストリームへ直接流すことでした。大きなレスポンスでは今でも有効な手法ですが、多くのフレームワークはデフォルトでメモリバッファリングを選ぶため見落とされがちな部分です
最近ならもちろん wasm でブラウザ上で望むものを動かせます。しかし当時の JavaScript はひどい状態で、デザイナーはせいぜい Photoshop ファイルを渡してくる程度でした。それをフレームとテーブルに切り分ける必要があり、Google Maps と Gmail が出たばかりの時期に、Netscape と Internet Explorer の両方をサポートしつつ、かなり JavaScript-heavy な CMS UI を作っていました
Firefox には特に厄介なバグがあり、文書内の HTML を実際の DOM としてレンダリングするために
disable-output-escapingが必要な場合、正しく動かず、生の HTML テキストとしてレンダリングされますずっと昔の、はるか彼方のディストピア的プロジェクトで、急速に変わるワークブックと並行してチームが Java 開発を調整できるはずがないと悲観した人が解決策を出しました
Excel で作られたワークブックを Visual Basic が XML に変換し、その XML に定義された Struts アクションを処理する Java クラスを XSLT ファイル群が自動生成する仕組みでした
https://raganwald.com/2008/02/21/mouse-trap.html
HN の議論: https://news.ycombinator.com/item?id=120379 · https://news.ycombinator.com/item?id=947952