- DTDが無いので、(amp, lt, gt, apos, quot は例外として)実体参照を書けない。
In HTML, all entity references are predefined and do not require a DTD. But because there is no DTD for XHTML5, entity references cannot be used in XHTML. (excluding the 5 predefined entities: &, <, >, " and ')
- DOCTYPE を廃した背景は「大抵のブラウザは DOCTYPE を読んでいない(意訳)」という判断らしいが。
- (X)HTML5 の XSD や RELAX NG での定義は、どうなんだろう。また XSD や RELAX NG では、実体参照の定義を どう扱っているのだろう。
- パーサーの解釈の関係で、noscript要素を書けない。
Finally the noscript is only conforming in the HTML syntax. It is not included in the XML syntax as its usage relies on an HTML parser.
Editor's Draft (3 November 2009) に 不要な部分をスクリプトの側で無効化するサンプルが紹介されており、この方法なら XML表現とも共存できる。特に、何らかの理由でスクリプトが中断され得る場面では noscript より好ましい解法と言えよう。
前記事の続報。
Javeline は、なんだか分からないエラーが出た。追跡調査する余暇なく使用断念。
AJAXSLT は、動かしてみたら重過ぎて断念。小規模な文書を変換するなら問題無いだろうと思うが、今回は入力文書の質、および想定する使用者のスキルから考えて「非現実的」と結論付けた。
結局、同「企画」では Sarissa のみを中核とする。
現在作成中のバージョンは、ユーザーインターフェイスの作成と動作確認、それにサンプルとして入力文書の調達を残すのみとなった。
時間があれば、次版では XSLT 処理を外部鯖に置き AJAX でブラウザに戻そうかと考えている。更に次の版では、全てを外部鯖内で処理させる。この段階で携帯端末での閲覧が可能になる。
懸念しているのはセキュリティ上の問題。踏み台にされたりとか。
- 小説原稿は鯖に固定か、全文を渡すか、URLのみ渡すか。
- XSLTスタイルシートは鯖に固定か、全文を渡すか、URLのみ渡すか。
全部を鯖固定すれば安全性は高いが、自由度は低い。また XSLT 関連モジュールを備える鯖は比較的珍しいため、設置場所と設置者のスキルが要求される。
スタイルシートを外部に置く場合、xsl:include で覗かれるのは嫌。
両文書(小説、XSLT)共、URL で指定する場合は、攻撃対象の URL を指定されると相手に申し訳ない。「robots.txt などで明示的に許可された物のみを読む」とか?
著者ならば小説原稿を POST できるが、読者はどうする? アップロード型掲示板のように原稿を扱うなら、著作権上の扱いが問題になるかもしれない。
手持ちのレン鯖アカウントでも中々 XSLT 対応のモノは乏しく、もし ECMAScript (JavaScript) で XSLT を扱えれば助かると思って探してみたら、有った。
- Javascript で実装された、google の AJAXSLT
- ブラウザ内蔵のエンジンを使う xslt.js
- 同じくブラウザ内蔵のエンジンを使う Sarissa
- pure javascript で書かれた XPath/XSLT 互換ライブラリ Javeline
先月から取り組んでいる企画では、Sarissa を使う方向で進めている。
最初に試した xslt.js は、周辺技術や Tips を知らなかったため悪戦苦闘。AJAXSLT を検討した。
AJAXSLT (Version 0.8, 0.8.1, 本稿執筆時点の trunk) は dom.js の xmlParse() が、XML コメント( <!-- foo > bar --> )中の「 > 」を誤認し、そこでコメントが終わった物として処理される。デバッグするか迷った最中に、Sarissa と出逢う。また、今回の企画ではサーバ・サイドでの XSLT 変換も視野に入れていた為、alert() を多用する AJAXSLT の手間を嫌ったという事情も有る。
Sarissa から Javeline が紹介されているものの、そのプロジェクトページは現在機能していない為、該当ファイルは別のプロジェクト中で取り込まれて居る物を拝借した。正規版を見付けたら換装する。
放り投げた xslt.js については、改めて調べれば巧く行くかもしれないし、行かないかもしれない。(未定、未検証)
Java の場合、XT や Xalan、Saxon が有るので問題にならないだろう。
XT の com.jclark.xsl.sax.Driver は、ソースで確認すると XMLProcessorEx か Parser の実装を要求している。
static void setParser(XSLProcessorImpl xsl) { String parserClass = System.getProperty("com.jclark.xsl.sax.parser"); if (parserClass == null) { parserClass = System.getProperty("org.xml.sax.parser"); } if (parserClass == null) { parserClass = "com.jclark.xml.sax.CommentDriver"; } try { Object parserObj = Class.forName(parserClass).newInstance(); if (parserObj instanceof XMLProcessorEx) { xsl.setParser((XMLProcessorEx)parserObj); } else { xsl.setParser((Parser)parserObj); } return; } // 中略 System.exit(1); }$SRC/xt-20051206/src/xt/java/com/jclark/xsl/sax/Driver.java
特に UTF 以外の encoding を扱いたい場合、XMLReaderAdapter クラスを指定しておけば何とかなるだろう。
$ java -cp xt20051206.jar -Dcom.jclark.xsl.sax.parser=org.xml.sax.helpers.XMLReaderAdapter com.jclark.xsl.sax.Driver input.xml input.xsl
Perl の場合、XML::XSLT (Version: 0.48) は未実装部分の機能を使いたい為、断念。また XML::DOM側の影響なのか、出力は日本語が実体参照になってしまって扱い難い。
なお XML::Parser に <?xml version="1.0" encoding="Shift_JIS"?> を読ませるため、下記コードを使用した。(Perl 5.8 系以降なら不要か?)
use XML::Parser::Expat; my %Encoding_Alias = ('shift_jis' => 'x-sjis-cp932'); foreach $key (keys %Encoding_Alias) { &XML::Parser::Expat::load_encoding($Encoding_Alias{$key}); exists $XML::Parser::Expat::Encoding_Table{uc $key} or exists $XML::Parser::Expat::Encoding_Table{uc $Encoding_Alias{$key}} and $XML::Parser::Expat::Encoding_Table{uc $key} = $XML::Parser::Expat::Encoding_Table{uc $Encoding_Alias{$key}}; }
これを XML::XSLT->new(Source => $xsl) 以前に実行させる。
Perl による実装が前提で、しかし XSLT に縛られないのであれば、私は STX に期待する。Perl 用に XML::STX が有る… ハズだったが、今は行方不明? CPANには居る。
可能であれば、XML::LibXML や XSL エクステンション、Xalan-C++ などコンパイル済みのライブラリを使いたい。その範囲では MSXML も、まあ、候補に残すとして。
ちなみに libxslt (version 1.1.24) は、DOCTYPE を明示すると期待通り(<p></p><br />)に空要素タグを出力してくれた。XT (20051206)、Xalan (2.7.1)、Saxon-HE (9.2.0.2)、内容の無い要素は全部が空要素タグになる。MSXML3 は、スタイルシートに書かれた通りに出力する。
<xsl:output method="xml" version="1.0" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" />
ま、これは出力の XML を DOM 等で受けて再整形すれば良いだけの話でもある。
PHP や他の言語による実装は調べていない。
必要に迫られて移植するのであれば、上掲の Java による実装を参照するのが現実的だろうか? C/C++ からだと等価な式を探すのが大変だし、他のは未実装の部分が有ったりするので。
「RSS 2.0 では xml:base が効かない」って話を以前に聞いていたが、ああ、此処に在ったのか。
まず link などの「URL」型要素について。
In all link and url elements, the first non-whitespace characters in a URL must begin with a scheme defined by the IANA Registry of URI Schemes such as "ftp://", "http://", "https://", "mailto:" or "news://". These elements must not contain relative URLs.
3. Data Types - 3.4 URLs
相対URLは MUST NOT の扱い。
次に description 要素に含まれる URL について。
The description should not contain relative URLs, because the RSS format does not provide a means to identify the base URL of a document. When a relative URL is present, an aggregator may attempt to resolve it to a full URL using the channel's link as the base.
4. Elements - 4.1.1.20.4 /rss/channel/item/description
こちらは、相対URLは SHOULD NOT の扱い。
アグリゲータによる相対URL の解消は MAY なんだよな orz。しかし /rss/channel/link 要素が基底URL と判ったのは収穫だった。ちなみに xml:base については言及なし。