読者です 読者をやめる 読者になる 読者になる

nXML-modeで使うRNC形式のスキーマを別形式のスキーマから変換して生成するgenrnc.elを作りました

これは何?

nXML-modeではバッファに適用するスキーマを切り替えることで、そのスキーマに沿った適切な入力補完、 いわゆるオムニ補完ができ、スキーマもユーザが追加で登録することができます。
が、登録できるスキーマRELAX NG Compact形式(拡張子がrnc)のスキーマだけのようです。
でも他の形式のスキーマも使いたい!
ということで、他形式のスキーマRELAX NG Compact形式に変換して登録する拡張を作成しました。

特徴

変換できるスキーマ形式

外部参照もまとめて登録

上記のどのスキーマもincludeやimportといった記述で外部のスキーマ定義を参照できますが、 使いたいスキーマのURLやファイルパスを指定するだけで、そのスキーマが参照しているスキーマも自動で登録されます。

登録したスキーマの更新/削除/名称変更

nXML-modeでは、登録するスキーマにはTypeIDという識別子を付けますが、その名称を変更したり、 スキーマに変更があったり不要になったりした場合に、TypeIDを指定してまとめて更新したり削除したりできます。

インストール/設定

ソース置き場

https://github.com/aki2o/emacs-genrnc

Emacs以外で必要なもの

  • Javaの実行環境

インストール

package.elを使う場合

2013/09/10 melpaリポジトリからインストール可能になりました。

el-get.elを使う場合

2013/05/03 現在el-getに登録申請中です。
2013/06/30 一向に登録される気配がありません。
2013/07/26 インストール可能になりました。ただし、まだmasterにしか登録されていません。

gitを使う

git clone https://github.com/aki2o/emacs-genrnc.git

genrnc.elがあるフォルダにlaad-pathを通す。 加えて、下記の依存拡張もそれぞれインストールする必要があります。

手動

上記URLからアーカイブをダウンロードして解凍し、genrnc.elがあるフォルダにload-pathを通す。 加えて、下記の依存拡張もそれぞれインストールする必要があります。

依存拡張

設定

(require 'genrnc)

;; スキーマなどを格納するディレクトリ
(setq genrnc-user-schemas-directory "~/.emacs.d/schema")

※その他のカスタマイズ変数については、M-x customize-group "genrnc" とかして下さい。

使い方

以下のコマンドが提供されます。

コマンド 説明
genrnc-regist-url 指定されたURLのスキーマファイルを登録します。
genrnc-regist-file 指定されたファイルパスのスキーマファイルを登録します。
genrnc-update-user-schema 指定されたTypeIDのスキーマを登録時のURL/ファイルパスから再度登録します。
genrnc-delete-user-schema 指定されたTypeIDのスキーマを削除します。
genrnc-rename-user-schema 指定されたTypeIDのスキーマのTypeIDを変更します。
genrnc-clear-cache キャッシュされた情報を消去します。

※本拡張はキーマップは提供しませんので、これらのコマンドは M-x genrnc-regist-url のように実行するか、必要なら適宜キーバインドして下さい。

スキーマ登録/更新

登録や更新に限らず、処理が完了した時には以下のようなメッセージを出力するようにしています。

[GENRNC] Finished ...

ただ、登録や更新の場合、そのスキーマのサイズや数によって、登録完了まで多少時間がかかるかと思われます。
ですので、コマンド実行後、上記メッセージが出力されたら完了と判断して下さい。
また、処理失敗時には以下のようなメッセージを出力するようにしています。

[GENRNC] Failed ...

また、稀に、正常終了のメッセージが出力された後、以下のようなエラーが出力され、 正常終了したのかわからなくなる場合があるかも知れません。

deferred error : ...

その場合は、面倒ですが*Messages*バッファにメッセージが出力されていないか確認して下さい。
上記エラーの原因はわかっていませんが、正常終了のメッセージが出力されていれば問題ないはずです。

登録/更新後の動作確認

nXML-modeのバッファにおいて、M-x rng-set-document-type-and-validate を実行して下さい。
このコマンドはデフォルトでは C-c C-s C-t にバインドされています。
TypeIDの一覧が表示され、登録時に指定した文字列がリストされているはずです。
それを選択すれば、バッファに適用されるスキーマが変わります。

キャッシュの消去

スキーマ登録などの際、各スキーマの処理状況やユーザの入力値をキャッシュとしてメモリ上に保持しています。
処理が正常終了している間は問題ないと思いますが、処理が失敗して再実行する時などに キャッシュが影響していると思われるメッセージが出力されたら、genrnc-clear-cache を実行して下さい。
このコマンドはメモリ上の状態を初期化するだけで、登録されたスキーマの情報には一切影響しないので、気軽に実行して問題ありません。

参照している名前空間スキーマの所在が不明な場合

XML Schemaのimport要素ではschemaLocation属性が省略されている場合があります。
そういった参照する名前空間スキーマの所在が不明な場合には、以下のプロンプトが表示されますので、 適切なURL/ファイルパスを入力して下さい。

[GENRNC] Including not located ns:'...'. Input PATH or URL locating this: 

保存されるスキーマ情報について

スキーマに関する情報は、genrnc-user-schemas-directoryに全て格納されます。
このディレクトリをコピーすれば、他マシンでも同じ状態になります。
このディレクトリに格納されている数字で始まるファイルが保存されたスキーマ、 index.txtが登録したURL/ファイルパスとスキーマファイルとの対応、 schemas.xmlがnXML-modeのrng-schema-locating-filesとして扱われるファイルです。

※これらのファイルを手動で修正することも可能ですが、 上記のコマンドを実行したりnXML-modeのバッファを開いた時点からindex.txtとschemas.xmlは 隠しバッファとして開かれ続けますので、ご注意下さい。

懸念事項

スキーマの変換処理はElispではなく、外部機能(※1)により実現しています。
が、その機能が完全とは言えないため、扱うスキーマの内容によって、 本拡張が制御できない部分で以下のような問題が発生することが考えられます。

  • 登録/更新でエラー(※2)になってしまい、登録できない。
  • 正常に登録できたのに、上記動作確認のrng-set-document-type-and-validate実行でエラーになり、そのスキーマが使えない。
  • 問題なくスキーマがバッファに適用できたが、表示される補完候補が正しくなかったり、正しい記述なのに文法エラーだと言われたりする。

実際、本拡張を作成する過程において、Web上に公開されているスキーマで動作テストをしましたが、 Try/Errorの繰り返しで、当初の予想より大幅に手こずりました。
私が遭遇した問題や、その回避方法などの内部処理に関して、別エントリにまとめます。
もし、上記の問題に遭遇して困った場合には参考になるかも知れません。

ただ、自分としては結構時間を使って頑張ったので、大体のスキーマは上手くいくのではと (ちょっと希望的な)推測をしています。

※1:TrangとXSDtoRNG.xslです。詳しくは別エントリで。

※2:その場合は、以下のようなエラーが出力されます。

failed convert by ...

その他

Enjoy!!!

あとがき

私は現在のところ、XMLを扱う機会はほとんどありません。
本拡張は必要になって作ったわけではなく、auto-complete-nxml.elを 作った時に、いろんなスキーマで試そうとして、何?RNCしか駄目なの?ってなったのがきっかけです。
そのため、数多くのスキーマを扱ったわけでもなく、そのスキーマを長く使ったわけでもありません。
上記に書いた通り、作り始めた以上、私が遭遇した問題には頑張って対応しましたが、 スキーマによっては多分上手くいかない場合があるだろうなというのが現在の正直な感想です。

ご連絡頂ければ、なるべく対処するようにします。