カテゴリー別アーカイブ: XML-DITA

【動画公開】「DITAで本を書いてAH XSL Formatterで自動組版する」、FormatterClub2021ウェビナーのお知らせ

2021年8月10日に開催しました、ちょっと一息アンテナハウスウェビナー「DITAで本を書いてAH XSL Formatterで自動組版する」の録画を編集した動画が公開されています。

動画は1本10分程度の4本立てとなりました。

ご好評いただけましたようで、当日は予定時間をはみ出すくらいにご質問をいただきました。
「タグを気にせず書きたい」といった意見もございました。個人的には「タグを気にしながら書きたい」派でしたのでそういった方のための資料はあまり用意できていなかったのですが、そういった方面のアプローチも存在しますので、機会があればあらためてまとめたいと思います。

さて、この動画自体は少し前に公開されたのですが、何故今ブログ記事にしているかというと、次のイベントに関連するためです。

FormatterClub2021ウェビナー開催

日時
2021年9月17日(金)17:00~18:10
概要
今回のFormatterClubでは、キヤノンの吉田一様にFormatterでのマニュアル作成と自動組版の取り組みの発表の他、XSL拡張仕様のご説明、AH Formatterの今後をご紹介を致します。
内容紹介・お申込みページ
ウェビナー登録ページ【終了しました】

Formatter Club は、アンテナハウスの XML 自動組版ソフト『AH Formatter』を導入されているユーザーや関心を持っていただいている皆様と開発者とを繋ぎ、会員同士の交流、情報交換により『AH Formatter』の利用技術を向上させ、より皆様のお役に立てる製品としていくために役立てることを目的として発足いたしました。
『AH Formatter』とその関連技術(XSL、CSS、XML 多言語組版など)に関心のある方でしたらどなたも参加できます。参加費は無料です。
Formatter Club の活動には会員メーリングリストを情報交換のために利用し、会員専用の Web ページも提供いたします。また定例会を開催し、会員相互の親睦をはかります。定例会は、『AH Formatter』開発者から最新バージョンの紹介・デモ、活用事例紹介、組版技術の向上のための勉強会などを行います。

Formatter Club について | アンテナハウス株式会社

ということで、「XSL拡張仕様のご説明」として『使いこなしガイド』の紹介をさせていただく予定です。
今回のウェビナーはFormatter Club会員様以外でも参加が可能ですのでお気軽にご登録、ご視聴ください。

関連記事



来週に迫る「DITAで本を書いてAH XSL Formatterで自動組版する」ウェビナーと溢れ話

以前ブログ記事でも告知しました*1「DITAで本を書いてAH XSL Formatterで自動組版する」ウェビナーを来週8/10(火)に開催します。

以前の記事で触れましたように、このウェビナーは『AH XSL Formatter拡張仕様使いこなしガイド』の制作報告であるものの、プレゼンの性質と時間の都合上、省略することはどうしても出てきてしまいます。

本記事では、省略した中から「実際の制作はLightweight DITAから始めた」ことについて書きたいと思います。プレゼンから省略された一番の理由は「説明がややこしくなる」なので、一度内容を忘れてウェビナー終了後にまたご覧になっていただくのも良いかもしれません。

実際の制作はLightweight DITAから始めた

Lightweight DITA

Lightweight DITA(LwDITA)はDITAのサブセットであるXDITAと、XDITAと互換があるよう設計したHTML5で記述するHDITA、MarkdownとYAML Frontmatterで記述するMDITAを指します。DITA-OTの新しめのバージョンではformat="mdita"のようにして通常のDITAトピックと同様に処理可能です。
LwDITAについては以前に少し記事を書きました。併せてご覧ください。

原稿形式選定

原稿形式選定にあたってのライバルは、様々な弊社出版物の実績があるCAS-UB、『Office Open XML Format入門』で利用されたsimpleDocといったものがありました。それらからの選定にあたって「執筆協力予定メンバー全員がそれらの原稿形式に慣れているわけではない」ということがあり、「原稿をプレーンテキストまたはHTMLで受けとれるならオーサリング作業は何とかなるだろう」という考えがあり、とりあえずということでLightweight DITAを採用することにしました。

  • マークアップが不足して困ったとき別形式に移行しやすそう
  • MarkdownやHTMLなら何とか書けるだろう

「~だろう」というふわっとした状態で制作をスタートしてしまったことが大きな反省点です。内部調整的な話は「連絡・相談をしっかりしよう」ということに尽きるのですが、技術的な面でも問題がありました。技術的な面と書きましたが、初歩の話です。

反省点

  • DLとTableの使い分けははっきりさせておこう
  • LwDITAのマークアップは最低限しかないので、DITAへの移行時にどうするかを詰めておく
  • LwDITAでもkeyrefは使える

DLとTable、これは仕様の表についての話ですね。仕様についての書籍ですので、山のように登場します。
HTMLのセマンティクスでも、仕様や会社情報の列挙にtableを使うべきかDLを使うべきかというのは混乱しやすいですし、一概に片方のみを正解とも言えません。今回の仕様の表については「1箇所につき1仕様」「左にラベル、右に内容という構成」を考えると、DLを使用していればミスを減らせたのではないか、と後から思いました。また、MDITAの簡易マークアップによる表はsimpletableになりますが、(望ましい形への自動変換を自前で用意しない限り、)ページ数その他についてシビアになる制作物では使わない方が良いでしょう。なんならテーブルマークアップは手で書かずにデータ変換処理によって用意した方が良いです。

MDITAの簡易マークアップによる表

| Header |
|--------|
| Cell   |

LwDITAのマークアップは最低限であることについて。XMLタグの<や>を表示時に補ってくれるXMLドメインなどはLwDITAでは使えません。MDITAではattributeに変換時のためのclass(HTML)なども使えませんから、使い分けが想定されるのであればトピック数が数百ファイルになる前に何らかの対処が必要でした。

LwDITAでもkeyrefは使えます。主に図版のパスの問題ですね。実は執筆当初使い方が分からかったので後回しに(書き方が間違っており上手く処理されなかった)したところ、後半の作業で牙を剥きました。

LwDITAを諦めた最たる理由はindextermが使えなかったことですが、これについては以前の記事で触れていますので割愛します。

こういった反省点を基にLwDITAをもっと上手くライティング形式として活用できる展望はあるのですが、最近はXMLでの読み書きに抵抗が薄くなったため、その機会はそうそう無いかもしれません。

ということで、来週8月10日(火)16時から、ちょっと一息アンテナハウスウェビナー『DITAで本を書いてAH XSL Formatterで自動組版する』を開催しますので、ご参加いただければ幸いです。また、『AH XSL Formatter拡張仕様使いこなしガイド』*2もよろしくお願いします。

DITAで本を書いてAH XSL Formatterで自動組版する

日時
2021年8月10日(火)16:00~17:00
概要
2021年5月18日に公開/販売した『AH XSL Formatter 拡張仕様使いこなしガイド』の制作報告を通し、XML執筆からPDFを作る過程の知見をご紹介します。
DITAについてや、DITAでの書籍制作における実例の紹介や、DITAを扱うときの注意事項など、自動組版やXMLの使い方、DITAに興味がある方、Formatterユーザーさん、必見です!
内容紹介・お申込みページ
こくちーずプロからお申し込み:https://www.kokuchpro.com/event/20210810/
Zoomウェビナーへ直接お申込みいただく場合: ウェビナー登録ページ

XSL-FO試行錯誤 変換後を意識しながら独自XMLを考える

業務ではなくプライベートの話となるのですが、自分用のXML規格を考えたり、そのXMLを変換するXSLTを書いたりということをしています。

自分用のXMLはさらに自分用の軽量マークアップからの変換によって得ることを想定しているので、スキーマまで作りこもうと日々ジリジリと進めています。

XSLTは組版用でないXMLを組版用のXSL-FOに変換できるわけですが、「軽量マークアップとして書きやすく、XSL-FOやHTMLにもしやすい」XMLというのはなかなか難しいなと感じています。

脚注はDITAではfnタグでマークアップします。XSL-FOではfootnote、footnote-bodyに変換されるでしょう。CSS Paged mediaではspanにした後フロートさせることが多いようです。
Webページ、HTML5的には脚注文の位置はasideの中あたりが良いのでしょうか?ただ、HTMLページの一番下(フッタ)に置いてしまうとPDFや紙でのソレよりも遥か下に行ってしまい、後注、しかもappendix的な配置になってしまうかもしれません。
では脚注用のfootnoteタグを用意するのではなくnoteタグを用意してレイアウトは属性にしましょうか?

変換先がXSL-FOであれば出力は1ファイルが望ましいでしょう。
しかしたとえばDITAなら?元の独自XMLはマップやトピックをどのように扱っていると好ましいでしょうか?独自XML自体が外部ファイルをどう扱うかも重要です。XIncludeなどを援用する、しない。うーむ。

メインの構造をまたぐ構造、たとえば複数段落に対する注釈などについてはrange-startとrange-endのようなタグを作る方式である程度しのげますが、変換後に納得できる構造にできるかは悩ましいところ。

そんなことを考えていると休日が過ぎています。
XMLアプリケーションはそれぞれがそれぞれの用途のために専門化されているので、中間形式のための独自XML規格というのは実は難しいのかもしれません。

DITAで本を書いてAH XSL Formatterで自動組版する

日時
2021年8月10日(火)16:00~17:00
概要
2021年5月18日に公開/販売した『AH XSL Formatter 拡張仕様使いこなしガイド』の制作報告を通し、XML執筆からPDFを作る過程の知見をご紹介します。
DITAについてや、DITAでの書籍制作における実例の紹介や、DITAを扱うときの注意事項など、自動組版やXMLの使い方、DITAに興味がある方、Formatterユーザーさん、必見です!
内容紹介・お申込みページ
こくちーずプロからお申し込み:https://www.kokuchpro.com/event/20210810/終了しました
Zoomウェビナーへ直接お申込みいただく場合: ウェビナー登録ページ終了しました


【ちょっと一息アンテナハウスウェビナー】「DITAで本を書いてAH XSL Formatterで自動組版する」を開催します【8/10】

本ウェビナーは終了しました。

の「ちょっと一息アンテナハウスウェビナー」の告知ページが公開されましたので、当ウェビナー担当者から、ブログ記事でもお知らせします。


DITAで本を書いてAH XSL Formatterで自動組版する

日時
2021年8月10日(火)16:00~17:00
概要
2021年5月18日に公開/販売した『AH XSL Formatter 拡張仕様使いこなしガイド』の制作報告を通し、XML執筆からPDFを作る過程の知見をご紹介します。
DITAについてや、DITAでの書籍制作における実例の紹介や、DITAを扱うときの注意事項など、自動組版やXMLの使い方、DITAに興味がある方、Formatterユーザーさん、必見です!
内容紹介・お申込みページ
こくちーずプロからお申し込み:https://www.kokuchpro.com/event/20210810/終了しました
Zoomウェビナーへ直接お申込みいただく場合: ウェビナー登録ページ終了しました

元々制作報告については何らかの形で行っていく予定でしたが、この度ウェビナーの形で紹介することになりました。

さて、「ちょっと一息アンテナハウスウェビナー」は平日にお時間をいただくこともあり、時間的にはかなりコンパクトになっています。『AH XSL Formatter 拡張仕様使いこなしガイド』の制作にあたっては、トピックとしては「XMLのこと」「XSL-FOのこと」「XSLTのこと」「PDFのこと」「DITAのこと」「学習にあたって参考にした資料のこと」「入稿のこと」「Antenna House XSL Formatterのこと」「原稿、レビューなどの社内環境のこと」など色々とあり、小さくまとめるのはなかなか難しいのですが、今回のウェビナーでは「既存資産がDITA文書ではない状況で、DITAを原稿とした書籍制作の報告」を軸に行う予定です。

上のように書き出してみるとよく分かりますが、XML組版、そしてそれに関連する技術を使うためには押えておく事項が多く「1から10まですべてやる」というのはかなり体力が必要です。自動組版を検討するにあたって「文書作成から組版までのどの過程を自分たちで行い、どの過程を自分たちではやらないようにするか」を判断する一材料としてもお役に立てるかもしれません。

ウェビナー開催まで少し期間がありますので、ご満足いただけるよう鋭意準備を進めていきます。



『Antenna House XSL Formatter 拡張仕様使いこなしガイド』を公開・発売しました

に『Antenna House XSL Formatter 拡張仕様使いこなしガイド』を公開しました。


Antenna House XSL Formatter 拡張仕様使いこなしガイド | AH Formatter XML関連出版物の紹介

また、弊社Webページで公開しているPDF版のほか、AmazonのPrint On Demand(POD)により印刷版をお買い求めいただけます。

Antenna House XSL Formatter 拡張仕様使いこなしガイド | Amazon

書籍の概要や目次についての詳細は紹介ページに掲載されていますが、この記事では少し短くまとめて紹介します。

本書は、W3C勧告のExtensible Stylesheet Language(XSL)1.1のFormatting Object(FO)から、アンテナハウスが独自に拡張した機能について解説しています。本書は次の4章構成です。

  1. 『ショウケース』
  2. 『Antenna House XSL Formatter 拡張仕様と応用例』
  3. 『PDF出力』
  4. 『その他の拡張』

『ショウケース』はAntenna House XSL Formatterを利用してどのようなレイアウトが可能であるのか、サンプルをどんと出してから、どのようにXSL-FOを記述しているかを項目に分けて説明しています。



『AH XSL Formatter 拡張仕様と応用例』では拡張仕様によって可能になる文書構造、利用例を逆引きで掲載しています。「行いたい表現」から対応する仕様を探す際などにお役に立てていただくことを想定しています。

『PDF出力』『その他の拡張』も拡張仕様の逆引き項目を主内容としますが、PDFに特化した機能は多岐に渡り、セクションでまとめるには大変な量となってしまうため、章として独立しています。『その他の拡張』は印刷やオプション設定など、文書内部とは関連の薄い項目をまとめています。

それぞれのトピックは、ほかのトピックへの言及は極力避け、目次、または最後に配置した仕様一覧へと頻繁にアクセスすることを想定した構成になっています。

さて、本書自体もAntenna House XSL Formatter V7.1改訂2版を用いて制作されています。
LwDITAで下書きを行い、DITAに変換し調整、修正を行った後、DITA-OTとPDF5-MLを基に拡張したプラグインでFOに変換、Antenna House XSL FormatterでAmazon PODの要求する仕様に沿ったPDFを出力、という工程です。この詳細についてはまたブログなどでまとめられればと思います。

Antenna House Formatterでは試用版をご用意しています。XSL-FOによる組版、そして本書で紹介しているような拡張を試用してみたい方はぜひお申込みください。
AH Formatter 評価版のお申し込み



LwDITAで(途中まで)ドキュメントを書いてみました

これまでに数回Lightweight DITA(LwDITA)に言及したことがありました。LwDITAやDITAについては記事末尾の関連記事、参考資料をご覧ください。ざっくり書くと、リッチな文書フォーマットとその簡略化版です。

最近、社内でドキュメントにLwDITAを試用して執筆しています。これは少し正確ではなく、より正確にお伝えするなら「執筆していた」となります。現在DITA(ただし一部機能しか使用しない)に移行中となります。

そこそこ文量のあるドキュメントに使ってみての利点、欠点について記そうと思います。一部、実装と仕様どちらに対しての言及であるのか不明瞭である点がありますがご容赦ください。

LwDITAでできること

DITAとしての利点と、LwDITAとしての利点があります。DITAとしての利点はおおよそ次のようになります。

  • DITA文書の一部としてDITA-OTで処理可能
  • conref、keyrefが利用できる
  • トピック単位でファイルを分けて管理できる
  • メタデータに索引用のキーワードを集約できる

LwDITAはDITA文書の一部として、通常のDITAと混在して処理が可能です。管理の観点からすると必ずしも良くはありませんが、「最初LwDITAで書いてDITAへ移行していく」今回の私のユースケースや、「既存資産のDITAやXML形式を利用しつつ新規記述のコストを減らす」といったときに有用です。

conrefやkeyrefはDITAの機能で、簡単に言えばプログラム言語における変数をドキュメント中に使用できます。専門語の揺れを防いだり、URLの変更などに対応できます。長期的に同じドキュメントを使用したいときに便利です。

「トピック単位でファイルを分割して管理できる」、DITAがトピック指向の設計であるので、条件が合致するときは各ドキュメントの構成のシンプルさを保つことができます。後述する「索引の半自動化」に係わるところです。「メタデータに索引用のキーワードを集約できる」というのも大体同じメリットですが、メタデータを書く箇所がフォーマット側で各ファイル単位に用意されているものは実はあまり多くありません。

そして1行では書きにくいメリットとして、構造のどの位置で呼ばれたかによって、適用されるセクションレベルを変更できるという恩恵があります。簡単に例を挙げると、h2レベルの内容の途中で呼ばれた別ファイルの見出しトップレベルはh3と解釈されます。書いているうちにトピックを分割したくなったときなどに有用です。

LwDITAとしてDITAに対する利点は次があります。

  •  単純な最低限のマークアップ(em、strong、italic、リスト……)

メディアコンテンツ対応も地味に仕様としてはDITA1.3より進んでいるのですが、これは出た時期によるもので、実用的にはDITAでも対応されているはず。

さて、とくにMDITA(と一部拡張プロファイルとしてHDITA記法)を利用していたのですが、次の利点があります。

  • MDITAではYAMLフロントマターにkeyword、category、author、source、トピックIDを記述可能
  • DITAに限らず別形式へ変換可能という安心感

メタデータは単純なKeyValue、あるいは簡単な入れ子となるようなものが多いため、汎用エディタを使ってXML形式で記述するのは冗長に感じるときがあります。YAMLでとりあえずパパっと書けるのは楽でした。

最終形をPDFと考えたとき、DITAではやりづらくなる箇所もあるかもということで、別形式にしやすい意味ではMarkdownは安心感があります。その分表現力に制約がかかりますが。

「チームメンバーの記述可能なフォーマットの共通スキルがHTMLやMarkdown」といったケースもありうるかもしれません。

LwDITAでできないこと

  • 対応しているDITAメタデータ(prolog)が少ない
  • 対応しているプロパティ、要素が少ない(特にMDITA)
  • 独自拡張のDITAが対応できない

さもありなんといったところで、作業が進むと、簡易形式ゆえにオミットされた機能が使いたくなってきます。上に挙げた理由で、今はDITA化を進行中です。とはいえ、変換後もLwDITAと対応できない要素はあまり使っていません。

とくにMDITAの不満点として、<note> に対応する記法がありません。以前あった記法もなぜかdepricatedになったので、注やtipsなど、荒涼としたドキュメントにおけるポップでおしゃれなアクセントが書けないのです。

XDITAを飛び越えてフルウエイトのDITAに変換すると、<indexterm>、索引語の指定が使えるようになります。keywordとしてYAMLフロントマターに記述していた語へこのマークアップを行うと、トピックの開始位置に索引が自動でつくように設定できます。入れ子にもできるので索引のサブ項目もほとんど労力をかけずに可能です。

「特殊化したDITA」について軽く触れましたが、AH-DITAという拡張ではfo:propプロパティによってXSL-FO語彙によるスタイル付けをダイレクトに行うことができます。また、図表のフロート配置も<floatfig>で、より自由に行えるようになります。

その他細かいところや全体像などについても、そのうち記事にできればと思います。

参考資料・関連記事


XProcの紹介

makeが良い、悪い」という話が一部で盛り上がっているのを見ました。
結局ツールなので、「用途に向いていなくても慣れなどを取る」か「学習が必要でも別のものを使う価値が見合う」かといった、状況に合わせた選択が必要になるでしょう。個人的にはファイルの絶対パスをハードコードするのは可能な限り避けてほしいですが。

ビルドツールにも様々な得手不得手があるものですが、XMLに特化したものもあります。そんな導入で、XProcの話題です。

XProc: An XML Pipeline LanguageはXML文書やその他の処理を記述するための言語です*1
W3CのページのAbstractには“Pipelines generally accept zero or more XML documents as input and produce zero or more XML documents as output.”とあります。ステップ処理として記述ができる、ファイル操作についてもある程度はできるなど他にもありますが、XSLTとは目的も書き味も結構違います。

2010年に1.0がW3C仕様として勧告された後、勧告としてはそれが最新の状態がまだ続いています。しかし、2020年8月19日にXProc 3.0の最終ドラフトが上がっており*2、期待が持てるようになってきました。Editor’s Draftは8月31日に更に更新されていますが。ちなみに2.0は諸般の事情で見送られています。

また、XMLPressから2020年4月に『XProc 3.0 Programmer Reference』(Erik Siegel)*3が刊行されています。W3CのXProc仕様のEditorであるNorman Tovey-Walsh氏による推薦文もついていますし、Erik Siegel氏も XProc 3.0 editorial teamのメンバーです。
XProc 3.0についてはドラフト版仕様とこの本を読むのが確実でしょう。

XProc 3.0でのもっとも大きな改良点はXSLT同様にXPath 3.1に対応したことだと思いますが、今回はXProcの雰囲気だけ紹介します。


<!-- 1. Pipeline document: -->
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" version="3.0">

  <!-- 2. Pipeline port declarations: -->
  <p:input port="source" primary="true" />
  <p:output port="result" primary="true" />
  <!-- 3. Convert document to HTML: -->
  <p:xslt>
    <p:with-input port="stylesheet" href="xsl/basic-conversion.xsl" />
  </p:xslt>
</p:declare-step>

上のコードは『XProc 3.0 Programmers Reference』*3「Getting started with XProc」にある例です。
<p:declare-step>がルート要素です。inputやoutputを省略できる<p:pipeline>も使用できますが、
2行程度では大して労力は変わらないですね。

XMLSchemaのネームスペースが宣言されているのは、XSLT同様asで型を明示できるからです。

書かれた処理を簡単に書けば、「入力をxsl/basic-conversion.xslのXSLTで処理し、出力へ渡す」ということになります。しかし、よくわからないプロパティportの存在がありますね。それぞれの指定で想像が付くかと思いますが、inputによる入力を処理対象(source)というportにつなぎ、with-inputによる入力は(XSLT)スタイルシートというportにつなぎ、このスタイルシートによってsourceを処理します。そしてresultというportにつながった出力へ結果を渡す、という流れです。こう書くと同語反復をしているように感じられるかと思いますが、それぞれのportにきたものをステップ処理していく流れが直観に近い記述で書けるということです。他のportとしては、スキーマの検証のスキーマを渡すためのschemaなどがあります。
<p:xslt><p:validate-with-xml-schema>はデフォルトのstepです。portは決まったstepと結びついていて、portに渡したものは結びついたstepが記述されていれば、そのstepで処理されます。デフォルトのstepとport、そして独自のstepと結びついた独自のportを記述していくことがXProcの基本となります。

*1 https://www.w3.org/TR/xproc/
*2 https://spec.xproc.org/lastcall-2020-08/head/xproc/
*3 https://xmlpress.net/publications/xproc-3-0/



XSLT 3.0(XPath 3.1)JSONをXMLに変換せずに利用する

先週はXMLの形にしたJSONを、XMLにしないまま扱う方法について紹介します。CSLはでてきません。

XPath 3.1*1で名前にJSONが入る関数は4つです。

  • fn:parse-json($json-text as xs:string?, $options as map(*))
  • fn:json-doc($href as xs:string?, $options as map(*))
  • fn:json-to-xml($json-text as xs:string?, $options as map(*))
  • fn:xml-to-json($input as node()?, $options as map(*))

$optionsについては説明しません。JSONをテキストとして引数にとるのがfn:parse-json()fn:json-to-xml()
fn:json-doc()は外部JSONファイルを読み込むときなどに指定します。fn:unparsed-text()で取得したテキストをfn:parse-json()へ適用するのと
大体同じことを行います。今回取り上げるのはfn:parse-json()fn:json-doc()についてです。

mapとarray

関係する名前空間は次に挙げるものです。

  • fn=”http://www.w3.org/2005/xpath-functions”
  • map=”http://www.w3.org/2005/xpath-functions/map”
  • array=”http://www.w3.org/2005/xpath-functions/array”

XPath 3.1のmap構造とarray構造は一般的なプログラミング言語におけるそれとほぼ同じもので、JSONオブジェクトをそのままの形で格納できます。
先週登場したJSONを見てみましょう。

{
    "items": [
        {
            "id": "7646893/2E3MJB9A",
            "type": "book",
            "title": "スタイルシート開発の基礎",
            "publisher": "アンテナハウス株式会社",
            "publisher-place": "Tokyo",
            "event-place": "Tokyo",
            "ISBN": "978-4-900552-23-4",
            "language": "ja",
            "author": [
                {
                    "family": "アンテナハウス株式会社",
                    "given": ""
                }
            ],
            "issued": {
                "date-parts": [
                    [
                        2016,
                        5
                    ]
                ]
            }
        }
    ]
}

このJSONを外部ファイルとして取り込むには次のように記述します。

<xsl:param name="input" >'exported-data.json'</xsl:param>
...
<xsl:variable as="map(*)" name="jsonMap" select="fn:json-doc($input)"/>
<!-- または -->
<xsl:variable as="xs:string" name="json-text" select="fn:unparsed-text($input)"/>
<xsl:variable as="map(*)" name="jsonMap" select="parse-json($json-text)"/>

XMLに変換した先週と、mapやarrayを活用する今回はこの後がまったく異なります。

次の記述で、先頭のtitleを一息で取得します。

<xsl:value-of select="map:get(array:head(map:get($jsonMap, 'items')), 'title')" />

まず、最も外側のmapから、itemsのキーを持つ要素を取得します(map:get($jsonMap, 'items'))。
キーitemsの値はarray型です。このままmap:get()を行おうとしてもできませんから、arrayの先頭を取り出すarray:head()を使用しています。ところで上の記述はパイプ演算子を使えば次のように書けます。

<xsl:value-of select="map:get($jsonMap, 'items') => array:head() => map:get('title')" />

mapのarrayでは、map:find()を利用することで指定したキーの値を配列で得ることもできます。挙動の詳細はXPath 3.1*1かXSLT 3.0*2のページを確認してください。

typeの値が何種類かに決まっていて、その種類を元にif文の判定をしたいのであれば、次のように書けます。

     <xsl:variable as="map(*)" name="item" select="map:get($jsonMap, 'items') => array:head()" />
      <xsl:if test="map:get($item,  'type') =  'book' or 'proceedings'">
      <xsl:value-of select="map:get($item, 'type')" /> <!-- book -->
      </xsl:if>

もちろんXMLの構造に変換しても同じことはできますが、より一般的なプログラミング言語に近い形で扱えています。

mapやarrayとして扱うために、JSONテキストとして記述してパースしたり、select="map{"key":value}"のような書き方をする以外に、<xsl:map><map-entry>を使うことができます。

mapの操作はエントリの追加やキー指定での削除などの他、map:merge()によるmapの統合、map:for-each()によるmap要素単位での関数適用などが可能です。arrayの方はarray:fold-left()array:fold-right()の畳み込み関数や、array:for-each()でarrayの要素ごとに関数適用などなど、XML形式を扱うよりもすっきりした構文で記述が可能な関数が用意されています。

注意しなければならないこととして、mapであるかarrayであるかを間違えるとうまく値を取り出せません。$itemnodeでもないので、直接xml-to-json()は使えません。

仕様やSaxonのドキュメントとにらめっこをしながら紹介してきたXSLT 3.0とXPath 3.1のJSONの扱いですが、誤りなどありましたらご指摘ください。

*1 https://www.w3.org/TR/xpath-31/
*2 https://www.w3.org/TR/xslt-30/


参考資料



Citation Style Languageの話(2) – 引用データJSONのXML化

前回引用データとスタイルの分離の必要性については述べていたので、CSL自体の歴史を見てみました。

Citation Style Languageの歴史について、
CSLのページ*1によれば、Bruce D’Arcus氏を中心に開発され、初期はZoteroのSimon Kornblith氏
がコントリビュートしていました。近年は Frank G. Bennett, Jr. と Rintze M. Zelleによって開発が主導されています。リンクが張られている2010年9月の外部記事はすでに読めなくなっていて、Blogは1.0のニュースリリース*2からです。

Wikipediaの記事*3にはその前身はBiblioXという取り組みであると記載されているのですが、2020年8月31日現在BiblioXのページは消失しており、辿ることが少し難しいようです。BiblioXの発表は2004年ですので、合わせれば15年以上の歩みとなります。

脱線しますが、URLが失効しあるものの歴史を辿るのが難しいというのは堪えます。Web Archiveなどのプロジェクトにしても、無限、無制限というわけにはいきません。それでも、参照した情報元が分かるよう引用情報を記述することの大事さを噛みしめています。

引用データのJSONをXSLTでXML化する

さて、CSLの引用データを確認してみましょう。Zoteroの出力一覧に「Citation Style Language …」という文字列が見えます。ポチッとな……無事ダウンロードされました。

「export-data.json」が。


{
    "items": [
        {
            "id": "7646893/2E3MJB9A",
            "type": "book",
            "title": "スタイルシート開発の基礎",
            "publisher": "アンテナハウス株式会社",
            "publisher-place": "Tokyo",
            "event-place": "Tokyo",
            "ISBN": "978-4-900552-23-4",
            "language": "ja",
            "author": [
                {
                    "family": "アンテナハウス株式会社",
                    "given": ""
                }
            ],
            "issued": {
                "date-parts": [
                    [
                        2016,
                        5
                    ]
                ]
            }
        }
    ]
}

引用データそのものは文書レイアウトのような複雑な構造を持ちませんし、XML形式である必要はないですからね。とはいえXSLTでこのデータを扱うにはどこかの段階でXMLに変換する必要があります。幸いなことに2020年のXSLTはJSONだって簡単に扱えます。今回はJSONがXSLT3.0で扱えることを示します。

XSLT 3.0 (というよりXPath 3.1)ではmap、arrayという頼もしい機能が用意されていますが、今回は構造に登場するだけです。次のテンプレートでは、外部ファイルであるexport-data.jsonを読み込んでXMLとして表示します。unparsed-text()でテキストファイルとしてJSONを読み込み、読み込んだJSONをjson-to-xml()でXMLにします。


<xsl:param name="input" >export-data.json</xsl:param>     
<xsl:template name="xsl:initial-template">
      <xsl:copy-of select="json-to-xml(unparsed-text($input))"/>
</xsl:template>

結果のXMLを次に示します。

<?xml version="1.0" encoding="UTF-8"?><!--export-data.xml-->
<map xmlns="http://www.w3.org/2005/xpath-functions">
  <array key="items">
    <map>
      <string key="id">7646893/2E3MJB9A</string>
   <string key="type">book</string>
      <string key="title">スタイルシート開発の基礎</string>
      <string key="publisher">アンテナハウス株式会社</string>
      <string key="publisher-place">Tokyo</string>
      <string key="event-place">Tokyo</string>
      <string key="ISBN">978-4-900552-23-4</string>
      <string key="language">ja</string>
      <array key="author">
        <map>
          <string key="family">アンテナハウス株式会社</string>
          <string key="given"/>
        </map>
      </array>
      <map key="issued">
        <array key="date-parts">
          <array>
            <number>2016</number>
            <number>5</number>
          </array>
        </array>
      </map>
    </map>
  </array>
</map>

XML形式で出力せずに扱う方が便利なこともありますが、とりあえず今回のところは得られた引用データのXMLから一部を抜き取ってFOにしてみます。

<xsl:template match="j:string[@key='title']">
    <fo:inline font-family="sans-serif">『<xsl:value-of select="." />』</fo:inline>
</xsl:template>
<xsl:template match="j:map[@key='issued']">
    <xsl:apply-templates select="j:array[@key='date-parts']"/>
</xsl:template>
<xsl:template match="j:array[@key='date-parts']">
<fo:inline><xsl:value-of select="./j:array/j:number[1]" />年</fo:inline>
</xsl:template>
<xsl:template match="j:string[@key !='title']">
</xsl:template>

これをexport-data.xmlに適用します。かなり省略していますが、
export-data.xmlのtitledate-partsから年の値を取り出し、加工して出力できました。

<fo:inline font-family="sans-serif">『スタイルシート開発の基礎』</fo:inline><fo:inline>2016年</fo:inline>

CSLからXSLT、XSL-FOへの完全な変換まで到達予定でしたが、XPath3.1やXSLT3.0の機能を調べだしたら今回の記事に間に合わなくなったため、少し時間を空けて再挑戦したいところです。

*1 https://citationstyles.org/about/
*2 https://citationstyles.org/2010/03/22/citation-style-language-1-0/
*3 https://ja.wikipedia.org/wiki/Citation_Style_Language

関連記事

  1. Citation Style Languageの話(1)

Citation Style Languageの話(1)

個人用途での電子書籍管理は引用管理ソフトウェアであるZotero[1]を利用しています。物理的な文書も登録管理できますが、蔵書量の関係からまだ手をつけていません。休日にちまちまと登録しているのですが、休日の度に本が増えるので終わりはしばらく来なさそうです。
書きもので技術的内容・事実に依拠した内容を扱うにあたっては参考文献が重要になりますが、参考文献の書式は学会や論文誌によって異なっているものです。つまり、書誌情報と書式を分離して管理、利用する仕組みが求められることになります。このうちオープンで普及しているものとしてはBibTeXといったものがあります。どんなものを使おうとおこる問題ではありますが、BibTeXを使うにはBiBTeXの記法やBiBTeXを処理するツールへの習熟が必要です。

さて、Zoteroではさまざまな形式で管理している参考文献リストを、プラグインによってMicrosoft Wordなどにも出力できます。そしてより柔軟にこのリストを扱うフォーマットとしてCitation Style Language(CSL)[2]というXMLに基づくオープンフォーマットが利用できます。
CSLを処理するスタンドアロンのソフトウェア*もありますが、XMLですのでXSLTによる処理も可能です。次のCSLはCSL primer[3]のページから一部抜粋しています。

<?xml version="1.0" encoding="utf-8"?>
<style xmlns="http://purl.org/net/xbiblio/csl" version="1.0" default-locale="en-US">
<!-- Generated with https://github.com/citation-style-language/utilities/tree/master/generate_dependent_styles/data/asm -->
<info>
<title>Applied and Environmental Microbiology</title>
<id>http://www.zotero.org/styles/applied-and-environmental-microbiology</id>
<link href="http://www.zotero.org/styles/applied-and-environmental-microbiology" rel="self"/>
<link href="http://www.zotero.org/styles/american-society-for-microbiology" rel="independent-parent"/>
<link href="http://aem.asm.org/" rel="documentation"/>
<category citation-format="numeric"/>
<category field="biology"/>
<issn>0099-2240</issn>
<eissn>1098-5336</eissn>
<updated>2014-04-30T03:45:36+00:00</updated>
<rights license="http://creativecommons.org/licenses/by-sa/3.0/">This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License</rights>
</info>
</style>

この基本情報と、テキスト中での引用書式、参考文献リストでの引用書式、
ロケールによる表示変更、その他書式のためのマクロといった要素を組み合わせたものがCSLの構造です。
つまり、XSLTを記述する方針は、テキスト中での引用書式cs:citation
参考文献リストでの書式cs:bibliographyの記述を元に出力書式を用意し、そこに情報を流しこんで出力を行うことになります。
cs:macroの内の記述方法などはXSLTと似通ってはいますが、if文でelse節が使えたり、variableやtextの使い方が異なるなど注意を要します。

来週はCSLの経緯の概略と、CSLからXSL-FOへの変換に挑戦予定です。


* CSLを利用できるソフトウェアのリストはCSLのトップページ[2]にあります。

[1] https://www.zotero.org/
[2] https://citationstyles.org/
[3] https://docs.citationstyles.org/en/1.0.1/primer.html

関連記事

Citation Style Languageの話(2) – 引用データJSONのXML化


Pages: 1 2 3 4 5 6 7 8 9 10 11 Next