RDF/XML構文を使ったサイトマップを書き直し、とりあえず構造は決定しました。
rss:itemsという語彙を何とかしたいところです。連結した展開名http://purl.org/rss/1.0/itemsを参照すると404というのはどういうことなのでしょうか。
今回気づいたのは、例えばPersonnelというサイト(リソース)をhttp://purl.org/jintrick/Personal/というURIで表してしまってはまずいということです。これはPersonnelというサイトのホームページに過ぎませんから。
というわけでまだPersonnelは匿名リソースなので、rdf:ID属性を付けて参照できる形にしたいところです。全ての匿名リソースにこれを行うなら命名規則をどうするかも考えなければなりません。
サイトマップが完成したら、RDFトリプルをどう扱うかを考える予定です。主語を割り出し、それについて何が述べられているのか、何を述べるか、そういった感覚で操作したいところです。何が述べられているのかが良く分からないときにはRDFスキーマを参照させるのですが、rss:itemsのようにそれが存在しないと困ります。
問題は、どんな変則的な構文にも対応できるようにするにはRDF/XML Syntax Specification (Revised) (英語)を舐めるように読みまわさなければならないことです。そこまでする必要があるのかどうかは兎も角。
ちなみに、私がやっているのは単なる修養であって、セマンティックウェブとは直接関係無いので注意が必要かもしれません。
GroupとDocumentという二つのClassといくつかのプロパティを定義したRDFスキーマ文書(site-concept.xml)のロケーションを間違えていたので修正。rss:itemsを批判する資格なし……。
今朝(昨日の朝)、dive into markの記事How to block spambots, ban spybots, and tell unwanted robots to go to hellにて、Hatenaアンテナが「rude bot」扱いにされアクセス制限をかけられていたことに気づいたので、はてなの代わりに? Mark Pilgrimさんに弁明してみました。
先ほど返事が届きまして、Hatenaアンテナを許可してくれるとのことです。
ここだけの話、どうしてもdive into markが読みたいというわけでもないのですが、あそこはとにかく影響力があるので、ロボットのリストを参考にされてしまった場合、英語圏の他のサイトの更新情報も取れなくなってしまう危険があったのです。
ある一つの文法に基づくXML文書群から、そのスキーマを定義するXML Schema文書を推論するというツール「Microsoft XSD Inference 1.0 」。オンラインで利用できるので使ってみたのですが……
一つのXML文書からinfer
とやらをしただけでは精度の低いXML Schema文書しか生成されないので、続けて他のXML文書でrefine
とやらをする必要があるのですが、結局最終的に自分の目で確かめないことには精度が怪しいのです。しかも出来あがったXML Schema文書は、型定義等がローカルな位置に散在しており、それらを一つ一つ微調整したりするのは苦痛でした。
やはりというか、フラットな位置に並んだ見出しの登場順序は検証できませんが、きちんと構造が明示された定型的なXML文書、例えばRSS文書用のXML Schema文書を作るのなら、ゼロから書くより効率的かもしれません。
XSLTクイズをやってみました。
XML: <snipsnap> <snip> <name>'2003-02-22</name> ... </snip> </snipsnap> XSLT: ... <template match="snip[number(substring(name,1,4))!=NaN]">...
http://dubinko.info/blog/2003_02_23_archive.html より
「子要素nameの(集合の)string-valueの1文字目から4文字目までを抜き出したものを引数にしたnumber関数の戻り値が、非数値(NaN)にならないsnip要素」にマッチさせるテンプレートのつもりなのでしょう。この誤りを指摘せよというクイズです。
まずこの比較式の右辺の「NaN」は、非数値(NaN)としてでなく、ノード集合として評価されてしまう筈です。
問題は、その「非数値」というデータ型を、XPathでどうやって表現するのかという点だと思います。私は明示的な方法を知りませんでしたので仕様書を見るという「カンニング」をしたところ、非数値(NaN)を返す関数が特別に用意されているわけではないようです。また、非数値(NaN)は、XPathではNumberのデータ型の特殊な形態であるということも分かりました。
結果的に非数値(NaN)を返す関数なら複数あります。最もシンプルそうなものはstring型のデータを引数にしたnumber関数でしょうか。
<template match="snip[number(substring(name,1,4)) != number('a')]" />
と、これで終了の予定だったのですが、MSXML君は両者を異なるオブジェクトと解釈するようです。仕様書を見てもNaN同士の比較についての記述を発見できませんでした。でもNaNは数値の一種なのですから……不具合?
<template match="snip[string(number(substring(name,1,4))) != string(number('a'))]" />
'NaN'という文字列同士の比較にすることで解決。XSLTを無理矢理に妥当性検証プロセッサとして使う時に役立つかもしれません。他のプロセッサではどうでしょう。
でも本当に非数値を明示的に表すXPath表現って無いのでしょうか。isNaN()みたいなブール値を返すものも無いようですし。何やら気持ちの悪いものがあります。
2.の答えが待ち遠しい。もしかして、ああいう形式の「質問」だったりして……1.はまさかとは思いますが。
二つの色をブレンドした色を割り出してくれます。ウェブページの配色に同系統以外を使いたいという方にお勧めです。Eric Mayerさん作。
お好みの色(コンセプトカラー)と、もう一色は明度、彩度の低い色か、色合いがそれほど違わない色を指定すると良いかもしれません。良く分からない場合は白(#FFFFFF)か黒(#000000)を指定すれば安全?です。
尚、前景色(文字の色)は、背景色の明度が高い場合は黒、低い場合は白にするのが無難です。それ以外にする場合、色弱の閲覧者(私含む)が読みにくくなるか全く読めなくなる可能性にご注意ください。モニターに映った色を信じず、明度の数値を比較するようにして頂きたいのです。
実際は「ブラウザで確認」する人が多いので、本気で読めないスタイルがウェブ上に1割くらい存在しています。だからこそユーザースタイルシートに凝るわけですけれども。ともかくHTML文書と同様、コントラストは「ブラウザで確認」すべきではないと思います。特に、部屋を真っ暗にしてCSSを作成すると大抵「誰かが読めない」スタイルが出来あがります。
個人的にホッとしたにゅーすです。実は今月上旬サイトマップ、RDF/XMLという記事の中で「海外のRDFに明るそうな人物のRSS1.0 feedを調べてみました。」と紹介させていただいた、Dave BeckettさんのDave Beckett's RDF Resource GuideのRSS1.0 feed (英語)、いやこれ自体は問題無いのですが、その直後、彼のWeblog(Dave Beckett - Journalblog)を発見しまして、そのfeedを見てみたところ……かなりガッカリさせられました。channel要素のrdf:about属性にfeed自身のURLではなくてサイトのURLが記述してあったからです。
「それはRDFトリプル的に変なのでは」というメールを(恐れ多くも)送ってみたわけですが、案の定中々返事がきません。ところが先日もう一度そのfeed(Dave Beckett - JournalblogのRSS1.0 feed)を見てみたところ、何時の間にか直っており、今朝メールの返事も頂きました。私のへんちくりんな英語のせいで半分しか伝わっていませんでしたが、まあ気にしません。
多分ツール(Movable Type? 良く知りません)が勝手に生成していたとか、その程度のことだったのだとは思いますけれども、なにしろBeckettさんはRDF/XML Syntax Specification (Revised)の編集者なので、私は物凄く不安だったわけでして。私の方がRDFを根本的に勘違いしている可能性に怯えていたわけですから。
このところ、つっこみのメールを全く頂きません。なにやらストイックな狂信者のように思われている節がありますが、別にそのようなことはないので間違いがありましたらご指導くださいますようお願いいたします。
というのも虫が良すぎる話なので、infoseek等を利用して積極的に探してみました。因みにこういうのをego-surfingというのだそうです。向こうのblog辞書に載っていたというだけで、実際にこの単語が使われているのを見たことは一度も無いのですが……。
この方がしっくりくる。Noteが見出しであるという意図も明示できているし、fieldset要素の目的上、他の要素とはっきりとした区別がつくよう、ブラウザによって表現されるはずだ。ただ、フォームコントロールとして誤解される恐れがあるのかどうかが心配。form要素ではないのだから大丈夫だとは思うけれども。
http://members.jcom.home.ne.jp/jintrick/Personal/d20027f.html#d5_2 より
form control group なので大丈夫ではないと思います。いわゆる table layout に通じる用法になってしまうかと。
そういう文書のマークアップには HTML は力不足ということになると思います。僕なら div でまとめちゃうかなぁ。
仰る通りです。とんでもないことを書いてしまいました。
ちょうど先日www-htmlを見ていて気づきました。こういう表題はtitle属性に書いておけば良いかな、と。IE系でレンダリングさせることができないとか、その辺りは知ったことじゃないと言う方向で。
『「どこどこの12月25日の記事」というテキストをa要素にして、フラグメント識別子つきのURIで表されるリソースにリンクしたとすれば、その断片は「記事そのもの」でなければおかしい訳です。見出しや空文字列にリンクする意図は無いのですから。』
http://members.jcom.home.ne.jp/jintrick/Personal/d200212l.html#d25_4 より
よくわからんのですが、要は、id=""やname=""のかかるタグ区間が、見出しだけなら「見出し」のみを参照したことになり、本文まで含めれば、本文まで参照されるという意味になる。という事らしいです。確かに、参照範囲が定められ、そこだけ抜き出して表示させられれば便利かもしれない?データーベースとして考えた場合は面白いかもしれない。
しかし、<a>要素がブロック要素をまたげない以上、<a name="" id=""></a>式で、全体を指定することは不可能な訳で。っていうか、こういうマークアップでnamazuにかけたら、表題=文章になって恐ろしいことになりそうな予感(笑。
にも関わらず、こういったidやnameはジャンプ先には一切使わないと豪語する引用元ページはすごいかも。この手の話を見て想うに、XHTML等の新しい習わしを古い習わしであるHTML4.01等に強引に適用するのは土台無理があると想うのですが...どうなんでしょ?みんながみんな新しい規格に移る義務はない...はずだよね、よね?
2003.01.02 参照範囲はどこなのか? @2003年01月 - くりすた日記 より
多分分かっていらっしゃいます。ただ、name属性は「HTML4.01の古い慣わし」では無い気がします。昔のことはよく知らんのですが、id属性が無かったHTML3.2 (英語)とかその辺りの時代の「因習」なのではないでしょうか。特に新しいことを言っているつもりも、XHTML特有の話をしているつもりもありませんでした。
みんながみんな新しい規格に移る義務はない
というのは全くその通りだと思います。むしろContent-Type:text/htmlでserveするなら、name属性にも頼る方が義務、というか仕様書的に見てストイックであると言えます。
参照:XHTML 1.0: The Extensible HyperText Markup Language (Second Edition) (英語)のC.8. Fragment Identifiers
text/htmlの場合、XHTML1.0 strictで後方互換性に配慮した形式で公開するのがW3Cの勧告に従うという意味で最も忠実だと思っていますが、私はXHTML1.0 transitionalに従っています。取り敢えずvalidであれば、文書型は何を使おうが問題にする方がおかしいかと。どこまで勧告に従うのかという基準は、個々人の事情に合わせて決めるのが一番です。
くりすた日記の部分識別子の示し方は、後方互換性を考える上で参考になりました。
単一のXML Schema文書で複数のXML文書を検証するための実用化に向けて動いてみました。
一番の問題点と言えば、ルート要素にxsi:schemaLocation属性(名前空間を持っている場合)あるいはxsi:noNamespaceSchemaLocation属性(名前空間を持っていない場合)を記述して、スキーマ文書へのリンクを作成しなければならない点です。より正確には、それらの属性を記述することによってパーサがスキーマ文書を必ず読み込んでしまうのが問題です。
パーサが賢ければ問題にはならない筈ですが、残念ながらMSXML君は自動でキャッシュを利用してくれることは無いようです。それどころか、standalone="yes"と宣言しても、あるいは、validateOnParse = false; と設定しても、ご丁寧に長大なスキーマ文書を読み込んでしまうようです。
どうしようもないので、先に挙げたxsi:schemaLocation属性やxsi:noNamespaceSchemaLocation属性を記述せずに、任意のスキーマ文書でそのXML文書を検証する方法を探ってみました。
MSXML4にはXMLSchemaCacheというものが用意されていました。
まずこのようにしてオブジェクトを作成します。
var cache = new ActiveXObject("Msxml2.XMLSchemaCache.4.0");
ここまでは良いのですが、私がやりたいのは任意のスキーマ文書をこの「キャッシュ」に含めることです。従って、参照先の例に挙げられているaddCollectionメソッドは使えません(結局例の長ったらしい属性を記述しなければならない)。addメソッドが使えます。
cache.add('', 'C:\\schema\\hub-jtr.xsd');
第一引数に名前空間URI(string)、第二引数にスキーマ文書のパス(string)を指定します。名前空間を持たない場合、第一引数は空文字列でOKなようです。
で、このキャッシュを検証したいXML文書に関連付けるにはどうするかというと、DOMDocumentオブジェクトのschemasプロパティにこのキャッシュを「代入」すれば良いらしいです。……甚だ不正確な表現です。正しくは、「IXMLDOMDocument2オブジェクトのschemasプロパティを、このキャッシュへの参照に設定する」と書けば良いのでしょうか。ややこしい表現です。
var doc = new ActiveXObject('MSXML2.DOMDocument.4.0');
doc.async = false;
doc.load('C:\\Documents\\index.xml');
doc.schemas = cache;
IXMLDOMDocument2オブジェクトのvalidateメソッドで実際に検証できます。このメソッドはIXMLDOMParseErrorオブジェクトを返却しますが、loadメソッドが完了した時点で作成されるIXMLDOMParseErrorオブジェクト(この例ではdoc.parseErrorで参照可能)が更新されるわけではない点に注意が必要かもしれません。私はここで引っかかりました。
var err = doc.validate();
if(err.errorCode !== 0)
alert(err.line + ' : ' + err.reason);
これで、「118 : DTDまたはスキーマによると要素の内容が正しくありません」なんてなメッセージを得られるわけです。
面倒くさいので、自作のgetErrorメソッドの引数にスキーマのキャッシュを指定する形で同様の結果を得られるよう、以上のようなプロセスを纏めてみました。しばらく使い勝手を試してみます。
なんで最近こんな時間(深夜3時)に更新するのかといえば、@NetHomeのFTPサーバが亀だからです。所謂「てれほたいむ」が始まった辺りから数時間、putしづらくて仕方なくなるんです。フリーのFTPソフトを使おうがDOS窓でFTP.EXEを使おうが、IEを使おうが同じです。夜な夜な巨大なバイナリデータを延々とputし続ける輩が存在するのでしょうか。勝手に想像して怒りに燃えています。
スタイルシートで変換したXHTML文書は、整形性は大抵保っているものの、バリデータにかけると悲惨な状態であることがしばしばあります。また大量の文書を処理する際、妥当でない文書を考慮に入れると大量のエラー検証用のコードを紛れ込ませなければならず非効率です。色々と必要性が出てきましたので、自家製XML用の妥当性を検証するためのXML Schema文書を書き始めました。
自家製XMLを書く際、このように別々の異なる名前空間をもった要素間で多重に入れ子関係を作るのは……
<body>
<j:dl>
<dt>foo</dt>
<dd>bar</dd>
</j:dl>
</body>
スキーマを書く際に死ねるので止めておいた方がいいです(自戒)。
その一端をメモしておきますと、上の例ではまずデフォルトの名前空間に関するスキーマの中で、jという接頭辞で表される名前空間のスキーマをインポートしなければなりません。さらに、そのjのスキーマの中で、内容モデルに使用する要素に関するスキーマをインポートしなければなりません。入れ子の数だけインポート。
targetNamespace属性で名前空間を決定するやり方が何となく糞っぽく思えてきたのですけど、気のせいでしょう、多分。
ルート要素直下に見出し要素を並べた「フラットな」文書の構造をチェックします。
<xsd:group name="Section1.class">
<xsd:sequence>
<xsd:element ref="h1" minOccurs="1" maxOccurs="1" />
<xsd:group ref="Text.class" minOccurs="0" maxOccurs="unbounded" />
<xsd:group ref="Section2.class" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:group>
<xsd:group name="Section2.class">
<xsd:sequence>
<xsd:element ref="h2" minOccurs="1" maxOccurs="1" />
<xsd:group ref="Text.class" minOccurs="0" maxOccurs="unbounded" />
<xsd:group ref="Section3.class" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:group>
<!-- 以下同様にSection6.classまで定義 -->
このSection1.classというグループを、ルート要素の型定義に含めて完成です。XSLTでの構造化に比べれば天国でした。尚、Text.classには、heading要素(h1?h6)以外のブロック要素(への参照)が含まれています。
自分で書いたのは殆どこれだけです。他は、Modularization of XHTML in XML Schema(W3C Working Draft 9 December 2002)のスキーマを修正(改ざん)して全体を仕上げました。所謂テキストノードの部分や属性値については、データ型がかなり緩いものが多いのでまだ調整中です。例えばこのようなもの:
<!-- a character encoding, as per [RFC2045] -->
<xsd:simpleType name="Charset">
<xsd:restriction base="xsd:string" />
</xsd:simpleType>
これでは制約が無いといっているに等しいわけです。
グローバルな位置にあるgroup要素の子要素(chice|sequence|all)にmaxOccurs属性かminOccurs属性が現れるとエラー。コンテクストに依存したエラーなのかどうか……。お陰でXHTMLのXML Schema文書を大幅に書き換えなければなりませんでした。定型的な作業なので面倒はありませんでしたが。
最も恐れていたのが検証の速度です。最も多い10kb程度のXML文書を検証するのに0.5秒くらい、最も大きい39kbのファイルで2秒弱でした。一括して検証するには遅すぎですが、新規作成時や更新時にチェックする分には問題無いレベルで一安心。
所謂「カメレオンスキーマ」を書いたのだけれども、やはり名前空間を持たせた方が長期的には良かったかもしれない。今のところメリットしか感じていないけれども、それはMSXML4のDOMがlevel1にしか対応していないからだろうなあ。