世界を動かす技術を、日本語で。

XSLT – ウェブのためのネイティブでゼロコンフィグのビルドシステム

概要

XSLTは1999年登場の ネイティブ なWeb向けビルドシステム。 現代の複雑なフレームワーク不要で 静的サイト 構築が可能。 XMLデータから HTML出力、ループや変数など多彩な機能。 主要ブラウザで クライアントサイド変換 対応、配布も容易。 シンプルなWeb制作の 有力な選択肢 として再評価。

XSLT:Webのためのネイティブ・ゼロコンフィグ・ビルドシステム

  • XSLT は1999年に標準化された、 XML→HTML変換 用の技術
  • 静的Webサイト制作でよくある構成
    • データ (.json, .md, .txtなど)
    • ビルドシステム (Hugo, Next.js, Astroなど)
    • 出力 (静的HTML)
  • 既存のビルドシステムは 複雑 で、理解や運用が大変
  • シンプルなHTML+CSSで作りたいが、 共通パーツ (ヘッダー・フッター)の管理が手間
  • ページ数増加で コピペ運用 が破綻
  • HTML importやWeb Componentsは JavaScript依存、純粋なHTMLだけでは困難

XSLTとの出会いとその特徴

  • ブラウザ 自体がビルドシステムになり得る発想
  • ブラウザは 多様なデータ形式 (text/html, application/xml等)を理解
  • RSSフィード の見た目改善をきっかけに XSLT に注目
  • XMLはHTMLに似ており、 データ記述が直感的
  • スタイルシート指定 も簡単
    • 例: <?xml-stylesheet type="text/xsl" href="blog.xsl"?>
  • XSLTで ループ・変数・インポート など、ビルドシステムに必要な機能を網羅
  • HTML出力 が容易に実現

XSLTの実践方法

  • XMLデータ例
    • <blog><post id="42" ...>...</post></blog>
  • XSLTスタイルシート例
    • <xsl:stylesheet version="1.0" ...>
    • <xsl:output method="html" indent="yes" />
    • <xsl:template match="/"> ... </xsl:template>
  • HTMLテンプレート として柔軟に変換
  • 動的データ も親XMLから参照可能
    • 例: <xsl:value-of select="title" />
  • 実行方法
    • XMLファイルをブラウザで開くだけ (例:Safariでblog.xmlを開く)
    • ブラウザが 自動でHTMLに変換・表示

XSLTのメリット・デメリット

  • メリット
    • ビルドツール不要、ゼロコンフィグで動作
    • 全ブラウザ対応、クライアントサイドで完結
    • 配布が容易、静的ファイルのみで運用可能
    • JavaScript不要、純粋なWeb標準のみで実現
    • XMLはHTMLに近く、直感的な記述が可能
  • デメリット
    • JSON非対応 (XMLデータ前提)
    • 高度な動的機能 や大規模サイトには不向き
    • 現代的な開発体験 にはやや古さも

まとめ:XSLTの再評価

  • XSLT は現代のフレームワーク全盛時代においても、 静的Webサイト 制作のための シンプルで強力な選択肢
  • Webブラウザ+XSLT で、 手軽かつ堅牢な クライアントサイド・ビルドシステム を実現
  • 古き良き仕様 が、今もなお 有用な道具 であることの証明

Hackerたちの意見

俺はシンプルな男。原始人のリードミー見たら、好きになった。時々、キーボード叩いてる原始人みたいな気分になるけど、いいこともある。ウェブサイトとかウェブ関連のことはやらないけど、XSLTについては知らない。XMLをちょっといじることはあるけど、ユーザーに何か見せたい時もある。いろんなファイル形式があって頭が痛くなるけど、きれいなものは好きだ。これ使うかも。仕様を読んでくれてありがとう。ツールを作ってくれてありがとう。

2000年代のエンタープライズXMLの肥大化が、技術を古臭く見せて、みんなを「クリーンな」JSONに向かわせたのは悲しいことだよね。XSLTやXPathはすごく成熟していて、今でも他のフォーマットで苦労している問題を解決してくれたのに。俺も悪い習慣に加担してるかもしれないけど、昔PHPのストリームラッパーを使ってXSLTのインクルードを(悪用して)楽しんでた思い出がある。これが古いバイアスかもしれないけど、ブラウザにローカルでやらせるのはちょっと不安なんだよね。昔は互換性の地雷原だったから。

XPathは、クエリのすべての部分に厳密に名前空間を指定しなくて済むなら、もっと良かったのに。

でも、XMLは実際にはインターネットで転送するには悪いフォーマットだよ。膨れ上がってて、帯域幅を余計に消費する。

XMLはまあまあだね。ちょっと冗長だけど、YAMLと比べるとその精度と表現力は評価してる。XPathもまあまあ。すべての構文を覚えるのは難しいけど、ちょっと試行錯誤すれば大体できる。XSLTは本当にクレイジーなナンセンスで、燃えて消えてほしい。

84年経ったけど、JSONにはXMLの「基本」が恋しいな。例えば、ちゃんとした標準化団体がないこととか。でも、スキーマのようなものはXMLの世界では(または、そう感じた)ずっとよく定義されていて、JSONの世界が追いつくのにほぼ10年かかった。私がXMLで最後にやったことは、EXIという技術で、XMLドキュメントを圧縮されたバイナリデータストリームに変換する転送方法だった。データ構造をASCIIに変換して圧縮し、HTTPで送信して、逆に同じことをするのはちょっと馬鹿げてるからね。今ではprotobufやその仲間が人気だけど、もしXMLが残っていたらどうなっていたんだろう。私の理想の考えでは、すべての互換性のある標準が互いに連携しているけど、例えばprotobuf/grpcとJSON APIの間には厳しい壁がある。良い方向に進んだのかもね?

2003年の『The Art of Unix Programming』で、著者はカスタムテキストフォーマットとそれに対するパーサーを書くことを勧めてたよね。手でXMLを書くのは、彼の言う戦争犯罪リストに入ってる。そこから、シンタックスハイライトやオートコンプリート、自動フォーマットのおかげで、手間が減ったし、寛容なパーサー(ブラウザがその代表)も悪評を受けることになった。現代のエディタでMarkdownやYAMLは存在するかな?

プロのソフトウェアエンジニアとしての最初のプロジェクトの一つは、19歳の時に雇い主が買ったGoogle Search Applianceをカスタマイズすることだった。彼らはCentOSを動かす黄色い顔のDellサーバーに何十万ドルも投資して、膨大なCIFSドキュメントストアのフルテキスト検索がビジネス開発プロセスを効率化すると思ってたんだ。2011年頃はXHTMLが流行っていて、GSAの運用方法はバックエンドからXMLで提供される検索結果をXSLTでXHTMLに変換することだった。俺はそのテンプレートを使って、企業のイントラネットポータルに似たものを、ColdFusionのアプリケーションページやStackOverflow、W3Schoolsのチュートリアルから盗んだアセットとマークアップを使って作り上げた。LinkedInで「XMLの専門家」としていろんなDoDの契約者から連絡が来た時、この経験は履歴書から外すべきだとすぐに学んだ。次に、JSONレスポンスからデシリアライズされたTypeScriptインターフェースの配列をJSXで反復処理する時、この投稿を思い出してほしい。俺はXSLTで同じことをやってたんだよね。

最近はXSLTを使ってフィードをスタイリングしてる。例えば: https://susam.net/feed.xml https://susam.net/feed.xsl

美しい!よくできてるね!みんながこれを自分のウェブサイトにコピーして、クリエイティブに使ってくれるといいな。

「XSLTがブラウザでネイティブに動く」って何それ?最後にXSLTを使ったのは20年前だけど、当時はめっちゃ使ってた。あの頃は、動かすために巨大で不安定なエンタープライズJavaのタワーが必要で、それがXSLTのエレガンスを損なってた。でも、もしXSLTが本当にブラウザで動くなら、ホストどこでも静的テンプレートの聖杯がずっと目の前にあったってこと?

2008年にブラウザでXSLTを使ったサイトで働いてたけど、サポートは2000年代初頭からあったと思う。

ブラウザはXSLT v1.0しかサポートしてないし、聞いたところによると、廃止の話も出てるみたい。v3のサポートを導入してくれた方が、テンプレートのネイティブサポートで静的ウェブページを提供しやすくなると思うんだけど。

それ、うまくいくよ。特に目立つのは、みんなが自分のAtomやRSSフィードをスタイリングして、別々のXMLやHTMLページを表示する代わりに使ってるところだと思う。https://rknight.me/blog/styling-rss-and-atom-feeds/

エンタープライズJavaの巨大でグラグラしたタワーを作って動かすのはそんなに悪くなかったよ。私たちはTomcatといくつかのApacheライブラリを使ってた。問題なく動いたよ。私たちのCMSは、埋め込まれたHTMLを含むXMLファイルを出力していて、キャッシュしやすかった。パーソナライズとHTML(およびJS)のレンダリングはサーバーサイドでキャッシングプロキシを使って処理してた。XSL変換はキャッシュの後に実行されて、たくさんのトラフィックに対応できる速さだった。ここでのXMLのポイントは、すべての準備されたHTMLをバイナリデータとして入れて、パーソナライズが必要なものをXMLタグとして扱うことだった。だから、最終的な変換はかなり速かった。XSLトランスフォーマーはかなり最適化されていて、出力をレスポンス出力ストリームに直接ストリーミングするのがコツで、全コンテンツをメモリにバッファリングしないことが重要だった。ちなみに、これは今でも良いテクニックで、ほとんどのフレームワークはデフォルトで間違っている。メモリバッファリングはユーザーにとって簡単だからね。大きなレスポンスには大きな違いを生むことがある。最近では、もちろんブラウザで好きなものをWASM経由で動かせるけど、当時はJavaScriptがめちゃくちゃで、デザイナーはせいぜいPhotoshopファイルを渡してきた。それをフレームやテーブルに切り分けなきゃいけなかった。GoogleマップやGmailが出たばかりの頃で、私たちはCMSのためにかなりJavaScriptを使ったUIを作っていて、NetscapeとInternet Explorerの両方に対応しなきゃいけなかったんだ。どちらもやり方が全然違ったからね。

あの頃は、動かすために巨大で不安定なエンタープライズJavaのタワーが必要だった。JVMとSaxonがあればそれで十分だったけど…。

まあ、ちょっと無理かもしれないけど、1. 1990-2000年代はブラウザが一貫性がなかったから、JSを使って同じように動かすようにした 2. その間に必要だったのは良いCSSスタイルだけど、それがまだ存在しなかった 3. 年を経るごとにブラウザは同じように動くようになった(主にハイランダーのルール - 一つだけ存在できるけど、Firefoxも頑張ってる) 4. でも、すでにすべてのブラウザでページを同じように見せるフレームワークに慣れてしまった 5. 現在の技術では、サーバー生成の古いスタイルのウェブページに対処できる。なぜなら、低いフットプリントで、速く動いて、メモリも少なくて済むから。なんでそう言うかって?最近、レガシーシステムからの移行に取り組み始めたんだけど、2000年代の標準的なページがHTTPリクエストごとに必要みたい。追加や削除などのアクションにはHTTPのリフレッシュが必要。でも、俺たちのReactシステムよりもずっと速い。理由は、1. 今のインターネットはずっと速い 2. スマホはたくさんのメモリを持っていて、JSフレームワークで無駄にされてる 3. バックエンドはほぼ同じ古い話 - CRUD CRUD CRUD(+ページネーション、+トランザクション)

現在の技術なら、サーバー生成の昔ながらのウェブページでも対応できると思う。軽量だし、動作も速いし、メモリもあまり使わないからね。ただ、高遅延のインターネット接続があると厳しいかも。

そのタイムライン、なんか違和感あるな。JSは行動を標準化するためにあまり使われてなかったし、ユーザーエージェント検出や、レイアウトを強制するためのバグ頼みが多かった。最初はDHTMLや後のAJAXのためのインタラクティブ性が主な目的だったと思う。レイアウト関連のことに簡単にアクセスできたわけでもなかったんじゃないかな?(間違ってるかもだけど)CSSも一貫性を持たせるのにはあまり役立たなかったし、できるようになってもまだゴチャゴチャしてた。確かにCSSガーデンは素晴らしかったし、みんなセマンティックマークアップに感動してたけど、テーブルをコーディングするのが普通だったしね。最初の2つのACIDを通過するのにすごく時間がかかった。フレームワークが「一貫した見た目」に影響を与えたかは微妙だな。jQueryを使わなくなった頃には、CSSが見た目を決めるものになってたし。まあ、長い時間が経ったから、もしかしたら記憶違いかも。

現在の技術では、サーバー生成の古いスタイルのウェブページに対応できると思う。低いフットプリントで、速く動いて、メモリも少なくて済むからね。私の.NET/Kestrel/SQLiteスタックは、SSRレスポンスを約4ミリ秒以内で出力できるよ。リリースビルドで動かすと、平均応答時間は数百マイクロ秒で測定される。ページごとに複数のクエリがあって、複雑な結合を使ってビュー特有のレスポンス形状を作成することも多い。HTML文字列を補間する前にデータを適切な形に整えると、100k行のテーブルを構築するような場合にパフォーマンスが本当に向上することがある。LINQは速いけど、行ごとにコレクションを具現化するようなアプローチは、アイテム数が増えるとすごく高くつくことがある。HTMLテンプレートエンジンとデータベースをできるだけ近づけることが、私の経験ではうまくいく秘訣だよ。結局、あの複雑な構造化DOMは、クライアントに送るためのバイトのストリームに過ぎない。StringBuilderや賢いSQLクエリを使えば済むのに、複雑なASTやパーサーのアプローチを心配するのは、無駄で自己満足の業界を生んでしまった。これまでに聞いた反対意見は、開発者がHTMLエスケープ関数を正しく使えないと思っている傲慢なセキュリティホールモニターたちのものばかりだ。

AJAXとDOMの更新は「速くするため」だけにあったわけじゃなくて、「ウェブサイト」や「ウェブドキュメント」のパラダイムを変えるために実装されたんだ。ウェブはドキュメントを表示するためのものだったからね。フルページリロードは、ドキュメントパラダイムで作業しているなら意味がある。HNではこれがうまく機能しているけど、他にも人々がJSフレームワークを使う代わりにシンプルなウェブサイトを作るべき例がたくさんある。でも「みんなフルページリロードに戻れる」ってのは本当じゃない。実際には、フルページリロードがひどいUXになるような「ウェブアプリケーション」がちゃんと存在するからね。要するに、「ウェブサイト」「ウェブドキュメント」「ウェブフォーム」はほとんどフルページリロードでやり過ごせるけど、「ウェブアプリケーション」は複雑なものを提示して操作する必要があって、フルページリロードは良い解決策じゃないってことだ。

俺は、XSLTをXMLテンプレートに使ってる会社で働いてたことがあるんだけど(今もそうかも)。あまり良くないし、もしできるなら移行したいと思ってるだろうな。1. 新しいXSLTの標準があるのに、XSLT 1.0がまだ主流なんだ。新しい標準と比べるとかなり限界があって変だし。2. XSLTテンプレートのパフォーマンス問題を解決するのは地獄だよ。XSLTはチューリング完全な関数型言語で、パフォーマンスはかなり抽象化されてる。ほとんどのドキュメントにはうまく機能するXSLTテンプレートがあったけど、あるドキュメントが約100行のテーブルを持ってきたら、爆発した。テーブルを処理するテンプレートがO(N^2)かそれ以上だったみたいで、最適化する明確な方法もなかった(各行にO(N)かそれ以上のXPathがあるかもしれない)。具体的にどう現れたかは分からないけど、確かそのドキュメントはXSLTで7分以上処理されてたと思う。JSにも他の問題はあるけど、アルゴリズムの複雑さの問題を解決できないのはその一つじゃない。

同じく。見たことあるいくつかの有名なサイトは、サイトマップをリクエストするだけで完全にダウンさせられると思う(1分間に何度もね)。ちなみに、これは実装の問題だとはいえ、私が見たXSLTプロジェクトの100%がそれを抱えてたってことは、言うまでもないかも。

商用版のSaxon使ってる?そんなに高くないし、機能(新しい標準も含めて)やパフォーマンスを考えると、個人的には価値あると思うよ。確か昔聞いた話だと、いろいろ賢い最適化をしてくれるみたい。

私の経験から言うと、ほとんどのシンプルなウェブサイトはXSLT 1.0で十分だし、パフォーマンスの問題もないよ。

一般的に言って、あの頃の「XMLが救世主」という考え方が問題の一部で、私たちがそれを離れた大きな理由でもある。XSLTでもSOAPでも、ある意味XHTMLでも関係ないけど… あれは機械同士が話すための機械言語として定義されてて、必ず何かがうまくいかなくなる。私たちが途中で介入するために作られてるわけじゃないし、できるけど、やるべきことよりずっと大変だよ。特に、機械が「間違った」り、違う「方言」を話すこともあるって考えられてなかったからね。見た目は素晴らしいけど、デザインして実際に展開すると、すぐに火がついて、何かを止めるとまた別の問題が始まる。

おかしいよね、XSLTは明らかに長いソースXMLを処理するのが普通だった時代に作られたのに、ネストされたループは明らかに問題になるし…。

俺が2002年頃、ティーンエイジャーだったときに、今でいうブログプラットフォームみたいなものを作ったんだ。それはASP、XHTML、XSLT、XMLを使ってた。当時のブラウザではうまく動いてたけど、振り返ると、ウェブアプリケーションをハッキングしてお金を稼ぐことができるなんて、10年後まで気づかなかったのが悲しい。

Epubって、これを一つのファイル/パッケージに圧縮したものなんだよね。だから、アマゾンみたいになれるかも ;)

人々はXMLの冗長性について文句を言うのが好きだけど、遠くから見ると複雑に見えるよね。でも、XMLを基にした良いファイルフォーマットを作って、DTDで検証して、必要に応じてXSLTで人間が読みやすくフォーマットできるのが好きなんだ。XMLはテキストベースのファイルフォーマットのC++だと思う。成熟していて、バッテリーも含まれていて、強力で、好きな言語で使えるからね。古くて成熟した言語には独自の癖があるけど、それについて文句を言うのが流行ってるのは悲しいことだ。使い方に合わなければそれでいいけど、忌み嫌うように扱うのは違うと思う。

3ヶ月前の(非常に)関連性のある投稿:Xee: RustでのモダンなXPathとXSLTエンジン https://news.ycombinator.com/item?id=43502291