XML Schema Inference
去年の11月頃に「英訳してmonologueに…」と書いていたXmlSchemaInferenceのネタを今頃になってのっけておきました。ついでにサンプルとか無理に手を加えてみたけど、content typeの説明の辺りで微妙に挫折。そもそもparticleとか、xsdに何があるのか知っている人が少なそうだ…
どこにくっつけようかと考えているので、実はまだorphan pageだったりして。
もともとはどこぞのフランスの大学院生が、XML文書からのスキーマ自動生成の論文か何かを書いていてRelaxngInferenceに行き着いたんだけどC#が読めないからアルゴリズムを教えてくれとかいう微妙な相談があったからなのだけど、あれはXmlSchemaInferenceと背景にある思想はだいたい似通っているので、実はあんまし書くことが無かったりする。そもそもRELAX NGはいくらでも文法が非決定的にできるから、合わなかったらchoiceで別ブランチを作って拡張とかあっさり出来ちゃうんだよね…つまりどんな枠組みを前提に作ってもだいたい無難に作れてしまうわけで、むしろ枠組みの設計の方が命題ではないかと思う。
How were expansions defined?
string s = "\u00E6\u0304";
Console.WriteLine ("\u01E3".Normalize (
NormalizationForm.FormD) == s);
Console.WriteLine (compareInfo.Compare ("\u01E3", s));
\u01E3というのは、aとeの合字にmacron(̄)がくっついたものなのだけど、Unicode Character Databaseでは、これは\u00E6\u0304と同じ文字という扱いになっている。\u00E6というのはaとeの合字で、\u0304はmacronだから、当然同じになっていてくれないと困る。
で、どういうことかというと、sortkeyを見た感じ、どうやら\u01E3は、macronがaとeの両方に付いたものとして定義しているっぽいのである。ということは、合字aeはどうがんばってnonspacing markで修飾しても\u01E3と同じ文字には出来ない、ということで…
ホントにこんなんで「UCAより良い」のだろうか…
ちなみにUnicode 1.1の時からそう決まっていたらしいから、UCAの時みたいに1995年に存在しなかったっていう言い訳は通用しないっぽい。
GetSortKey() is a hack
invariantCompareInfo.Compare ("A\u0308\u0301", "\u1EA6");
ベタっと書くと、前者は”Ä́”で後者は”Ầ”。戻り値は0。
うーん、本当にこれで本当にUCAよりWindows collationの方が優れていると言えるのか? 正常系としてはAに対してdiaeresisとacuteが同時に付くことは無いようではあるけどさ。だんだん信用ならなくなってきた。
というわけで、sortkeyの解析を続けているのだけど、level 2のsortkeyの値については非常にやっつけっぽい実装になっているなあと感じる。nonspacing markが連続した場合、そのlevel 2の値は単純にprimary weightを持つ文字のlevel 2の現在値に加算される。そして256を超えるとあふれた桁を無視して0に戻る。
そもそもnonspacing markだけでも256文字以上存在するので、1バイトですむって事はかなりあり得ない1のだから、やっぱ設計上無理があるだろうと思う。
そんなわけで日本語だのタイ語だのアラビア語だのには特別な加算処理が行われているんだとずっと思っていたけど、どうもそうではなく、みんな単純に加算されているだけっぽい。これらのlevel 2の値が単に1とか2とかなのね。
Footnotes
-
理屈としてはlevel3以降に違いをもつことがあり得るので不可能ではないが、case insensitiveになれば同一になるnonspacing markというのは滅多に存在しない。存在はしていたと思う(けど定かではない)。 ↩