ホーム 記事一覧 ブック DH週間トピックス 検索 このサイトについて
English
TEI/XMLサイトをVercelで高速デプロイ:XSLT変換をsaxon-jsで自動化する

TEI/XMLサイトをVercelで高速デプロイ:XSLT変換をsaxon-jsで自動化する

はじめに TEI (Text Encoding Initiative) に準拠したXMLデータをXSLTでHTMLに変換し、Webで公開する構成は、デジタルヒューマニティーズの分野で広く使われています。 従来、ブラウザのクライアントサイドXSLT変換(<?xml-stylesheet?>やJavaScriptによるXSLTProcessor)でXMLを表示するケースが多いですが、この方式にはいくつかの課題があります。 ページを開くたびにブラウザがXSLT変換を実行するため、表示が遅い SEO・クローラー対応が難しい ブラウザごとのXSLT実装差異 本記事では、Vercelのビルド時にXML→HTML変換を自動実行し、生成済みHTMLを静的配信する方法を紹介します。 構成 project/ ├── docs/ # Vercelの出力ディレクトリ │ ├── index.html # トップページ │ └── data/ │ ├── *.xsl # XSLTスタイルシート │ ├── *.sef.json # コンパイル済みスタイルシート │ ├── *.xml # TEI/XMLソース │ └── *.html # 生成されるHTML(ビルド時生成) ├── build.js # ビルドスクリプト ├── package.json └── vercel.json Node.jsでのXSLT処理ライブラリ比較 Vercelのビルド環境ではネイティブツール(xsltproc等)が使えないため、Node.jsのXSLTライブラリを使う必要があります。以下の3つを検証しました。 xsltproc(参考:ローカル環境) macOSに標準搭載されているC言語実装のXSLTプロセッサです。 xsltproc docs/data/main.xsl docs/data/劉興我本巻一.xml > docs/data/劉興我本巻一.html 一瞬で完了しますが、Vercelのビルド環境では利用できません(apt-getが使えない)。 xslt-processor(純JavaScript実装) npm install xslt-processor GoogleのAJAXSLT(2005年)をベースにES2015+に更新したライブラリです。ブラウザにXSLTサポートがなかった時代のpolyfillが起源であり、1400行程度のXMLファイルの変換でも数分以上かかり、実用に堪えませんでした。 遅い理由は以下の通りです。 XPath式を実行時に毎回パース・評価する(キャッシュや事前コンパイルの仕組みがない) 最適化戦略がない設計のため、XPath評価が累積的に重くなる 純JavaScriptのDOM実装による木構造走査のオーバーヘッド saxon-js(Saxonica社製) npm install saxon-js xslt3 XSLT 3.0仕様の編集者であるMichael Kayが率いるSaxonica社が開発した高性能XSLTプロセッサです。最大の特徴は事前コンパイル方式にあります。 ...

TEI/XMLサイトをVercelで高速デプロイ:XSLT変換をsaxon-jsで自動化する

TEI/XMLサイトをVercelで高速デプロイ:XSLT変換をsaxon-jsで自動化する

はじめに TEI (Text Encoding Initiative) に準拠したXMLデータをXSLTでHTMLに変換し、Webで公開する構成は、デジタルヒューマニティーズの分野で広く使われています。 従来、ブラウザのクライアントサイドXSLT変換(<?xml-stylesheet?>やJavaScriptによるXSLTProcessor)でXMLを表示するケースが多いですが、この方式にはいくつかの課題があります。 ページを開くたびにブラウザがXSLT変換を実行するため、表示が遅い SEO・クローラー対応が難しい ブラウザごとのXSLT実装差異 本記事では、Vercelのビルド時にXML→HTML変換を自動実行し、生成済みHTMLを静的配信する方法を紹介します。 構成 project/ ├── docs/ # Vercelの出力ディレクトリ │ ├── index.html # トップページ │ └── data/ │ ├── main.xsl # XSLTスタイルシート │ ├── main.sef.json # コンパイル済みスタイルシート │ ├── source.xml # TEI/XMLソース │ └── source.html # 生成されるHTML(ビルド時生成) ├── build.js # ビルドスクリプト ├── package.json └── vercel.json Node.jsでのXSLT処理ライブラリ比較 Vercelのビルド環境ではネイティブツール(xsltproc等)が使えないため、Node.jsのXSLTライブラリを使う必要があります。以下の3つを検証しました。 xsltproc(参考:ローカル環境) macOSに標準搭載されているC言語実装のXSLTプロセッサです。 xsltproc docs/data/main.xsl docs/data/source.xml > docs/data/source.html 一瞬で完了しますが、Vercelのビルド環境では利用できません(apt-getが使えない)。 xslt-processor(純JavaScript実装) npm install xslt-processor GoogleのAJAXSLT(2005年)をベースにES2015+に更新したライブラリです。ブラウザにXSLTサポートがなかった時代のpolyfillが起源であり、1400行程度のXMLファイルの変換でも数分以上かかり、実用に堪えませんでした。 遅い理由は以下の通りです。 XPath式を実行時に毎回パース・評価する(キャッシュや事前コンパイルの仕組みがない) 最適化戦略がない設計のため、XPath評価が累積的に重くなる 純JavaScriptのDOM実装による木構造走査のオーバーヘッド saxon-js(Saxonica社製) npm install saxon-js xslt3 XSLT 3.0仕様の編集者であるMichael Kayが率いるSaxonica社が開発した高性能XSLTプロセッサです。最大の特徴は事前コンパイル方式にあります。 ...

XSLT処理を5倍高速化:Saxon-JSからSaxon-HEへの移行

まとめ TEI XML → HTML変換において、npx xslt3(Saxon-JS)からJava Saxon-HEへ切り替えたところ、ビルド時間が1分48秒から23秒に短縮された(約5倍の高速化)。 背景 校異源氏物語テキストDBは、源氏物語のデジタルエディションで、54巻分のTEI XMLファイルを持つ。ビルドスクリプト(Python)が各XMLをHTMLに変換するため、npx xslt3を54回呼び出していた。 python3 scripts/prebuild.py xsl # 全54巻のXSLT処理 この処理がビルドパイプライン全体で最も時間のかかるステップだった。 ベンチマーク ファイルごとの比較 巻 文字数 npx xslt3 (JS) saxon (Java) 高速化率 01 桐壺 11,240 1.8秒 1.1秒 1.6倍 34 若菜上 46,230 4.9秒 0.4秒 12倍 ファイルが大きいほど改善幅が大きい。JVM起動コスト(約1秒)を差し引くと、実際の変換処理は桁違いに速い。 合計(全54巻) npx xslt3 (Saxon-JS): 1分48秒 saxon (Saxon-HE): 23秒 移行手順 ローカル環境(macOS) brew install saxon ビルドスクリプト SAXON_JAR環境変数 → saxonコマンド → npx xslt3の順にフォールバックするヘルパーを追加した。 def xslt_cmd(xsl, src, dst): """Return XSLT command, preferring Saxon-HE over npx xslt3.""" saxon_jar = os.environ.get('SAXON_JAR') if saxon_jar: return ['java', '-jar', saxon_jar, f'-xsl:{xsl}', f'-s:{src}', f'-o:{dst}'] if shutil.which('saxon'): return ['saxon', f'-xsl:{xsl}', f'-s:{src}', f'-o:{dst}'] return ['npx', 'xslt3', f'-xsl:{xsl}', f'-s:{src}', f'-o:{dst}'] GitHub Actions Node.js + xslt3をJava + Saxon-HE jarに置き換えた。 ...

TEI Processing Modelで実現する宣言的なマルチフォーマット変換

TEI Processing Modelで実現する宣言的なマルチフォーマット変換

はじめに TEI (Text Encoding Initiative) は人文学テキストのデジタル化において広く使われている標準規格です。本記事では、TEI P5で導入された Processing Model という機能を使って、TEI XMLから複数のフォーマット(HTML、LaTeX/PDF、EPUB3)への変換を実現した事例を紹介します。 https://www.tei-c.org/Vault/P5/3.0.0/doc/tei-p5-doc/en/html/TD.html#TDPM 対象プロジェクトは「校異源氏物語」で公開されているテキストを例とします。 https://kouigenjimonogatari.github.io/ 背景 これまで、以下の記事で紹介したように、変換処理を個別に行ってきました。 ODD/RNGファイルのカスタマイズによる、使用するタグの限定 XSLTを用いたHTMLへの変換 XSLTを用いたTeX/PDFへの変換 EPUBへの変換 それぞれの取り組みにおいて、個別の変換ルールなどを記載したファイルを作成する必要があり、その煩雑さが課題となっていました。 Processing Modelとは Processing Modelは、TEI要素の変換ルールを宣言的 に記述する仕組みです。従来は各出力フォーマット用に個別のXSLTを書く必要がありましたが、Processing Modelを使うことで: ODDファイル内で変換ルールを定義 できる 複数の出力フォーマット に対応可能(web、latex、epubなど) スキーマと変換ルールを一元管理 できる Processing Modelの構造 <elementSpec ident="persName" mode="change"> <desc>Personal name</desc> <model> <!-- HTML output --> <modelSequence output="web"> <model behaviour="inline"> <outputRendition>span</outputRendition> <desc>Inline span for person name</desc> </model> </modelSequence> <!-- EPUB3 output --> <modelSequence output="epub"> <model behaviour="inline"> <outputRendition>span</outputRendition> <desc>Inline span for person name in EPUB3</desc> </model> </modelSequence> <!-- LaTeX output --> <modelSequence output="latex"> <model behaviour="inline"> <outputRendition>\person</outputRendition> <desc>Custom LaTeX command for person names</desc> </model> </modelSequence> </model> </elementSpec> 主な要素: ...

VSCodeとXSLTを用いたTEI/XMLのリアルタイムプレビュー

VSCodeとXSLTを用いたTEI/XMLのリアルタイムプレビュー

概要 VSCodeとXSLTを用いたTEI/XMLのリアルタイムプレビュー環境を試作したので、備忘録です。 挙動 動作例は以下です。TEI/XMLファイルを編集し、保存すると、ブラウザの表示内容が更新されます。 https://youtu.be/ZParCRUc5AY?si=-aHHi3bIZGWoJYnP 準備 以下の拡張機能をインストールします。 Live Server Trigger Task on Save TEI/XMLを保存した際に、Trigger Task on SaveによってXSLTを実行し、変換されたHTMLファイルをLive Serverで閲覧します。 リポジトリ サンプルコードを以下に格納しています。 https://github.com/nakamura196/tei-xml-xslt-vscode XSLTを行うにあたり、xslt3をインストールします。 git clone https://github.com/nakamura196/tei-xml-xslt-vscode cd tei-xml-xslt-vscode npm install settings.jsonとtasks.json .vscodeフォルダに、settings.jsonとtasks.jsonを格納しています。 tasks.jsonは以下です。xsl/make-CETEIcean.xslを用いて、XSLTを行うタスクを設定しています。 { "version": "2.0.0", "tasks": [ { "label": "Transform XML with XSLT", "type": "shell", "command": "npx", "args": [ "xslt3", "-xsl:xsl/make-CETEIcean.xsl", "-s:${file}", "-o:${fileDirname}/${fileBasenameNoExtension}.html" ], "presentation": { "reveal": "never", "close": true }, "group": { "kind": "build", "isDefault": true }, "problemMatcher": [] } ] } xsl/make-CETEIcean.xslは、CETEIceanで公開されているXSLファイルです。 https://github.com/TEIC/CETEIcean/blob/master/xslt/make-CETEIcean.xsl 次に、settings.jsonです。teiフォルダ以下のxmlファイルに対して、保存時に上記のタスクを実行します。 { "triggerTaskOnSave.tasks": { "Transform XML with XSLT": ["tei/*.xml"] } } これらの設定により、TEI/XMLファイルを保存時に、同フォルダにHTMLファイルが作成されます。 ...

校異源氏物語テキストDBのTEI/XMLからPDFを作成する

校異源氏物語テキストDBのTEI/XMLからPDFを作成する

概要 校異源氏物語テキストDBは、『校異源氏物語』のテキストデータを公開するデータベースです。 https://kouigenjimonogatari.github.io/ 今回、本DBに以下のようなPDFファイルを追加しました。 https://kouigenjimonogatari.github.io/output/01/main.pdf 本記事は、上記のようなPDFファイルを、XSLTとTeXを使って作成します。 リポジトリのクローン 以下のように、リポジトリをクローンします。 git clone --depth 1 https://github.com/kouigenjimonogatari/kouigenjimonogatari.github.io そして以下のコマンドにより、xslt3をインストールします。 npm i xslt3 https://www.npmjs.com/package/xslt3 XSLファイルの作成 今回は、まずTEI/XMLファイルをTeXファイルに変換します。 以下のようなXSLファイルを作成しました。 https://github.com/kouigenjimonogatari/kouigenjimonogatari.github.io/blob/master/xsl/tex.xsl <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tei="http://www.tei-c.org/ns/1.0"> <xsl:output method="text" encoding="UTF-8"/> <xsl:template match="/"> \documentclass[a4paper,11pt,landscape]{ltjtarticle} \usepackage{xcolor} \usepackage{luatexja-fontspec} % fontspec を LuaTeX-ja と共に利用 \usepackage[top=2cm,bottom=2cm,left=2cm,right=2cm,textwidth=25cm]{geometry} % スタイル定義 \newcommand{\person}[1]{\textbf{\color{blue}#1}} \newcommand{\place}[1]{\textit{\color{green}#1}} % 日本語フォント設定 \setmainjfont{Noto Serif CJK JP} % 日本語フォントを指定 \title{<xsl:value-of select="//tei:title"/>} \date{} \begin{document} \maketitle % 本文 <xsl:for-each select="//tei:seg"> <xsl:apply-templates/> \par\medskip </xsl:for-each> \end{document} </xsl:template> <!-- 人名の処理 --> <xsl:template match="tei:persName"> \person{<xsl:value-of select="."/>}</xsl:template> <!-- 地名の処理 --> <xsl:template match="tei:placeName"> \place{<xsl:value-of select="."/>}</xsl:template> </xsl:stylesheet> 先にインストールしたxslt3を使って、以下のようにTEI/XMLファイルをTeXファイルに変換できます。 ...

XSLTを使ってIIIFとTEIの対照表示を実現する

XSLTを使ってIIIFとTEIの対照表示を実現する

概要 XSLTを使ってIIIFとTEIの対照表示を実現してみる機会がありましたので、備忘録です。 結果は以下からご確認いただけます。「校異源氏物語テキストDB」を利用しています。 https://kouigenjimonogatari.github.io/xml/xsl/01.xml 背景 TEI/XMLの可視化にあたって、これまでは、TEI XMLをHTMLに変換してブラウザ上で表示するためのJavaScriptライブラリであるCETEICeanを使うことが多かったです。 これらの取り組みではJavaScriptのフレームワークと合わせて、柔軟な開発が可能でした。 しかし、この方法ではTEI/XMLとは別に、ビューアのデプロイが必要であるなど、課題を感じる点もありました。 対策 そこで、XSLTを使ったIIIFとTEIの対照表示に取り組みました。以下のXSLファイルを用意しました。実装にあたっては、ChatGPTを利用しました。 https://github.com/kouigenjimonogatari/kouigenjimonogatari.github.io/blob/master/xsl/mirador.xsl そして、XMLファイルからは、以下のように参照します。相対パスとなっている点は、適宜読み替えてください。 <?xml version="1.0" ?> ... <?xml-stylesheet type="text/xsl" href="../../xsl/mirador.xsl"?> <TEI xmlns="http://www.tei-c.org/ns/1.0"> <teiHeader> <fileDesc> <titleStmt> <title>校異源氏物語・きりつぼ</title> <author>池田亀鑑</author> ... これにより、以下のようなXMLファイルをブラウザで表示すると、 https://kouigenjimonogatari.github.io/xml/xsl/01.xml 以下のように、IIIFとTEIの対照表示を実現することができました。ページのリンクやMiradorビューアの前後ボタンのクリックにより、テキストと画像が同期します。 このようにXSLTによる可視化を行うことにより、別途のビューア開発やデプロイが不要となり、またxslファイルの更新による容易なカスタマイズを実現することができました。 考察 Next.jsのようなフレームワークとCETEIceanを組み合わせてビューアを作成する方法と、本記事で紹介したようなXSLTを使った可視化方法について、ChatGPTに使い分けを聞いてみました。 結果、以下のように、比較的単純な可視化ではXSLT、高度なインタクラションが求められる場合はCETEIcean、を選択するのがよさそうでした。 1. 高度なインタラクションが必要な場合: Next.js + CETEIcean Next.js はReactベースのフレームワークで、クライアントサイドレンダリングやサーバーサイドレンダリング、APIの統合などを柔軟に行えます。Next.jsを使うと、複雑なUIや状態管理、ナビゲーション、動的なデータ処理が必要なアプリケーションの構築が簡単です。 CETEIcean は、TEI XMLをそのままHTMLにレンダリングするためのライブラリで、特にクライアントサイドでTEIを動的に表示したい場合に便利です。CETEIceanを使うと、JavaScriptを使ってTEI要素を直接操作できるため、ユーザーがクリックした際に特定のページに遷移したり、アノテーションの追加など、インタラクティブな機能を実装できます。 利点 : リッチなインタラクション(ページナビゲーション、フィルタリング、ユーザーの操作に応じた動的なUIの更新など)が容易。 コンポーネントベースの設計が可能で、保守性が高く再利用性も高い。 さまざまなJavaScriptライブラリやプラグイン(Mirador、Annotoriousなど)との統合が容易。 2. 単純な表示や静的な構造でよい場合: XSLT XSLT は、XMLデータをHTMLなどに変換するためのテンプレート言語で、サーバーサイドまたはクライアントサイドでの静的な表示に適しています。XSLTを使用すると、TEI XMLをシンプルなHTMLとして表示できます。 利点 : 軽量で設定がシンプル。ブラウザがXSLTをサポートしていれば、特別な環境を必要とせずに、直接HTML表示が可能。 HTMLとして生成されるため、CSSによるスタイルの適用が容易で、簡単なナビゲーションや静的なページリンク程度なら実装も比較的簡単。 静的なレポートや閲覧専用のデータの表示に最適。 判断基準のまとめ 高度な機能やインタラクティブな要素が求められる :Next.js + CETEIcean 例:クリックやスクロールに応じて動的にデータをロード、複数のナビゲーションや検索機能の提供、アノテーションや画像ビューワーの統合。 単純な表示がメイン :XSLT 例:TEIドキュメントをただ表示するだけ、特定の要素にスタイルを適用して閲覧しやすくする、シンプルなページナビゲーション。 まとめ ビューアを使用せずに、TEI/XMLファイルとXSLファイルのみで閲覧環境を実現することは、管理や運用コストの低減にもつながるように思いました。 ...

Node.js で XSLT を実行するサンプルリポジトリを作成しました。

Node.js で XSLT を実行するサンプルリポジトリを作成しました。

Node.js で XSLT を実行するサンプルリポジトリを作成しました。 https://github.com/ldasjp8/nodejs-xslt TEI/XMLファイルなどをNode.jsで処理する際の参考になりましたら幸いです。