殆ど私的なメモと化していますが……。
Standards are bullshit. XHTML is a crock. The W3C is irrelevant.
Semantic obsolescence@dive into mark より
は?
まあともかく、ツッコミどころ満載のステキな記事を公開してくれたお陰で色々と面白そうな所をまた発見できた。凄い騒ぎだ。
流し読みしただけなのでハイパーリンクにはしません。
ユーザースタイルシートを使っていて、h1要素に自作の背景画像が現われたのでおかしいと思ったらclass="soleil"に出くわした。http://www.la-grange.net/
http://www.jayallen.org/journey/2003_01.php#002281 このdivの量。かといってdivを無視すると恐ろしく読みづらくなるサイトがあるし……。div div div{ padding: 0; margin: 0; border-style: none }あたりかなあ。
「何を今更」とか「草案ですよ」とかいった突っ込みは見られたものの、XML名前空間を使えばいいという意見が見られなかった。
www-html@w3.org from January 2003: XHTML 2.0 considered harmful (英語) 。懲りないなあ。「有害と思われ」。
グルも反応している! って私はミーハーですか。
Then again, given that you can take XML and CSS and create your own documents out of whatever markup language you can invent, and use XSLT to bridge the gap between old browsers and new ones, I find XHTML to be of minor import.
Tuesday, 14 January 2003@Eric's archived thought より
そうでした。 XSLTがそのギャップを埋めることが出来ます。でもMayerさんのように(文字の大きさを考慮して)h2要素をすっ飛ばしたりする制作者がいるから、h1?h6は破棄される方向に行くんじゃあないですか? ……いやそれは違うかも。
そして石川先生も登場 (英語) 。citeは安泰、と。噂どおり何かの間違いだったというところか。さて啖呵をきってしまったPilgrimさんの立場は……。heading要素辺りについてもまだ決まったわけじゃあないしねえ。
しかし凄いな。Pilgrimさんの影響力。私の中では株が激減しましたが。まあ、きりが無いのでもう寝よう。
tableレイアウトに関する疑問をメールで頂きました。折角ですから返事はここに公開することにします。折角書いても一人にしか伝わらないメールよりは良いかなあくらいの理由です。
現在、多くのサイトでHTMLのtable要素がレイアウトを調整する為に使われているようですが、まず、これを二つのケースに分けます。
前者
後者は取るに足りませんので無視しますが、現在は前者のようなケースが圧倒的に多い為、tableはレイアウトを実現するのに好都合なのです。
これは言い換えれば、折角情報を「意味として」伝える手段が用意されているのにも拘わらず、その力を放棄しているとうことです。大多数のユーザーは、現在PCやMacでWWWブラウザを使ってウェブサイトにアクセスしていますから、その現状をそのまま反映しているのでしょう。ですから例えば、携帯端末からのアクセスが大多数であるサイトではtableレイアウトは使用されません。
「今現在における大多数」を最も重視するなら、tableレイアウトは有り得る選択肢です。
これは、ユーザースタイルシート等によってウェブページの見た目を閲覧者が好きなように変更できるという利点を失わせます。
「見栄えを閲覧者の好きにさせたくない」と考えるなら、tableレイアウトは有り得る選択肢です。
この他、Why avoiding tables (for layout) is important (英語) に挙げられているような弊害を覚悟し、納得出来るのであれば、tableレイアウトは有り得る選択肢です。
ですから、「何故多くのサイトがtableタグを誤用してレイアウトとして使っているのか」と問われれば、無知であるか、あるいは以上に挙げた選択肢を選択する制作者が多い、と答えます。尚、彼らには「HTMLの文法や仕様」等は眼中にありません。何故なら、現在の多くのWWWブラウザは「文法ミス」を補正するよう設計されているからです。
tableは、飽くまでもWWWブラウザには表としか解釈されませんから、例えばブラウザのウィンドウの幅を狭めたとしても、あるいはユーザースタイルシートを使ったとしても、セルの配置関係を崩すことはありません。意味が変わってしまいますから。つまり、現状の多くの閲覧者の閲覧環境が変化し、もっと小さな表示領域で閲覧することが主流になったならば、tableレイアウトは無闇矢鱈と横幅を占有する悪しきレイアウトになりますから、自然、減ってゆくと思われます。変化が無ければ、特に減りはしないと思われます。
時代だとか閲覧者の主流な環境だとかに左右されないデザインを目指すなら、tableレイアウトは選択肢には入りませんし、視覚的なデザインよりも内容の伝達を重視する制作者にとってtableレイアウトは余計な異物でしかありませんから、前者のような制作者を対象にしないこのサイトでtableレイアウトを推奨することは最初から有り得ないわけです。
「tableレイアウトが今後どうなってゆくのか」言い換えれば「閲覧者の主要な環境がどう変化してゆくのか」について、私はあまり興味がありません。
tableレイアウトを廃止し、同じようなレイアウトをCSSで行うには、多くの場合div要素型を使うことになります。
しかしそのような発想は、ウェブページのデザインを行う際の順序として「あべこべ」です。
あるウェブページに「ナビゲーション」と「コンテンツ」があったとします。制作者は、「ナビゲーション」を左側、「コンテンツ」を右側に配置したいと考えました。しかしここで初めて「レイアウトの為のdivを使う」と発想が出てきた時点で、それはHTMLにおける情報デザインの失敗を意味します。
本来の手順はこうです:
このような手順を踏んだにも拘わらずCSSでのレイアウトがうまく行かない場合、諦めることも肝心です。しばしば、そのような「レイアウト」は情報を上手く伝える為に余計な手段となっています。デザインとして失敗するでしょう。
HTMLの仕様で定義されていない要素は特にマークアップしないという選択肢もあります。これは、ウェブページの構成要素を出鱈目に認識してしまう危険を防ぐ手段として有効です。複雑なレイアウトをすることが出来なくなったり、情報の単位を思うように示すことが出来なくなりますが、一方、テキストエディタで編集する制作者にとって視認性が良くなったり、利用できるCSSが限定されることによって、素人が考える出鱈目な「視覚デザイン」を予防することが出来ます。
また、div要素やspan要素は、CSSスタイルシートでのレイアウトに便利である為よく使われますが、前述の「HTMLの仕様で要素型が定義されていれば、それを用いてマークアップを行い、」という手順をすっ飛ばす制作者がしばしば存在することが示す通り、これは陥りやすい罠である為、最初はこれらを禁止してみるという行為も推奨されて良いはずです。
あまり興味ありませんが、一応適当に具体的な手段を紹介します。
「ナビゲーション」を左側、「コンテンツ」を右側に配置したいと考えるなら、CSSのfloatプロパティを裏技的に使えます。
<div class="navigation">[ナビゲーション]</div>
<div class="contents">[コンテンツ]</div>
div.navigation{
float: left;
width: 30%;
}
div.contents{
float: right;
width: 55%;
}
堅苦しい話に飽きた方は息抜きにどうぞ。
この記事を推敲する際に一部参考にさせていただきました。「tableレイアウトはある条件の元有り得る」を連呼しているのはこの記事の影響です。わらい。
Document Object Model (DOM) Level 2 HTML Specificationこんなんでました。縦長ーな文書で保存に1分かかりました。「HTML完全」とかで保存した私が馬鹿。
Note: The interfaces provided in this document are only for [HTML 4.01] and [XHTML 1.0] documents and are not guaranteed to work with any future version of XHTML.
1.3. XHTML and the HTML DOM より
というわけでXHTML1.1には無関係なのです。DOM2 HTML のgoalとしてto provide convenience mechanisms, where appropriate, for common and frequent operations on HTML documents.
とあるものの、「便利な機能」といっても、精々私にはHTMLTableSectionElementのinsertRowメソッドとかHTMLSelectElementのaddメソッドとかしか思い当たりません。莫大な量のデータを扱うサイトがあって、table系の要素を動的に生成するようなケースで無い限りは必要ではない気がします。気がするだけかもしれませんが。
何が言いたいかというと、こういう記述があったからといってXHTML1.1を止めてXHTML1.0に戻してもあまり意味がないということです。確かに私のサイトはXHTML1.0でしかもTransitionalですが、これはMIME typeが好い加減なJCOMサーバーの都合とかiframe要素を使いたいとか、しょうもない理由があるのでして、決して安易に「参考」にしないで頂きたいのですという意思だけは表明しておきたく。また確かに私はMSXMLユーザですが、「XHTML1.1をパースできない」なんて馬鹿なことはありませんので気にしないで下さい。あんなバグは、どう考えてもユーザ側が何とかすべき問題で、例えば私の場合、例の上出来なDTDを改竄させてもらってそちらへリダイレクトするようにProxomitronのフィルタを作りました。
1.0から追加されたもので便利そうなのはHTMLObjectElement, HTMLIframeElement, HTMLFrameElementのcontentDocumentアトリビュートくらいしか見つかりませんでした(節穴かも知れません)。src属性等々でリンクが明示された文書のHTML Documentオブジェクトへの参照です。Mozillaはフライング実装済みですし、IEは別の方法(framesコレクション経由のアクセス)があります。ともかく時期IEの登場に先駆けて勧告されたので、IE7(もしくはIE.NET?だったかなんだったか)での実装が期待されます。というか、実装判別はDOM1 HTMLで行っているのに、contentDocumentをMozilla向けに使ってしまっていたことに気づきました。修正しなければ。
Apple 純正 MacOSX デフォブラウザ Safari 発表とのことです。
そのためにcss discussが大騒ぎになっています。レビューを投稿する人もいて結構迷惑なのですが、 Josh Hughes (英語)さんの投稿によるとKonquerorというブラウザと同じ「CSSの裏技」が有効なのだそうです。centricle : css filters (css hacks) (英語)に一覧表があります。
この二つだけですか?
Safari開発メンバーのDave Hyatt氏が、Mark PilgrimさんのSafariレビュー (英語)に自身のWeblog上で返事を書かれています。
HTML4.0 TransitionalなWeblogで、<link rel="alternate" type="text/xml" title="Confessions of a Mozillian" href="http://www.mozillazine.org/weblogs/hyatt/blogger_rss.xml"></link> なる記述があったりします。終了タグは兎も角、「alternate」が問題です。あなたみたいな人がいるからッ!
(参考記事:Re: XML encoding of RSS feeds (英語))
CSS guruのSafariレビュー (英語) にも反応してもらいたいところ。
などと書いていたら、本当にCSS guruのSafariレビューに反応 (英語)がありました。と思ったら全然興味のない箇所に言及されていてガッカリです。ある意味興味深いのですけどね(謎)。
一番上のだけブックマークすれば事足りるような気がします。さすがというか。
ふとしたことから、日本語以外の言語で書かれている文書にリンクしているa要素に、hreflang属性をつけて見ようと思い立ちました。というか、その作業の際間違えてagendaを空更新してしまった事に気づいたので(謎)急いででっち上げた文章です。こんなことを書く予定はありませんでした。
サイト内全文書についてこれを行うとなると、手作業ではやる気がしません。レスポンスヘッダから言語に関する情報を得られれば完全自動化できた筈だったのですが、日本語以外の言語で書かれているかどうかを判別する手がかりとしては、結局のところリンクしているリソースのURIしかありませんでした。従ってある程度の手作業が必要でした。
href属性を持ちつつhreflang属性を持たないa要素は、XPathで次のように特定できます。
このロケーションパスにマッチしたa要素を抜き出します。
href属性に、ne.jp, or.jp, gr.jp, ac.jp, japan, 等々、日本語を匂わせる文字列が含まれたURIがあった場合、そのa要素を切り捨てます。
残ったa要素をリストアップします。この際に、言語を選択するためのラジオボタンも一緒に生成しました。GUI的に操作する為、HTML文書として作成します。私がJScriptに拘る理由がここにあるわけです。
100個ほどのアンカーについて、手作業で終了リソース(リンク先)の言語を判別しました。ラジオボタンをチェックする形です。
手作業で行った言語情報を元に、DOMインターフェイスを使って全a要素にhreflang属性を与えます。
さて、ここでやってしまいました。XPathをミスったのです。
var uri = elmA.getAttribute('href');
// elmA : リストアップした個々のa要素
var sXpath = 'descendant::a[string(@href) =' + uri + ']'
リストアップした個々のa要素のhref属性値と同じhref属性値を持ったソース文書中のa要素を、Xpathを使って特定する箇所です。JScriptを使っていますが、データ型については別の頭を使わなくてはならないことをすっかり忘れています。次のようにURIにstring関数を適用しなければなりませんでした:
但し、これはMSのDOM独自拡張メソッド「selectNode」を使う際の注意事項で、XSLTの文脈においては、述語内に$foo のような形で変数参照を書くことが出来ます。
ちなみに、ソース文書は名前空間無しのXML文書ですから、ノードテスト(a)に名前空間接頭辞が要りません。
ともあれsetAttributeでhreflang属性を付加し、文書を保存して終了。for文でぐるぐる回すわけです。今回の台本で滅多に使わないDocumentFragmentを利用しましたが、次回更新時にその部分を紹介してみたいと思います。
hreflang属性を手がかりに、アンカーの隣に国旗の画像か何かをつけてみるのも面白いかも知れません。a要素にマッチするXSLTテンプレートを修正することになるわけですが、問題は「どこまでやるか」です。ISO 639 (英語)にhreflang属性の取り得る値が色々出ていますが、これら全てを考慮に入れるわけにも行きません。
と、ここまで書いて、言語と国に必然的な関係など無いことに気づきました。
年始に行った文書構造やマークアップの修正等をメモしておきます。
闇黒日記(平成14年3月3日)の記事を参考にして、フッタに見出しをつけました。例:
<h3>Foot note</h3>
<address>この記事のURI : <span class="uri">http://foo.com/bar.html#baz</span></address>
div要素
タグを全て取り払った時に、文書構造的に妥当であるかという点を反省してみました。div要素を取り払ったら何も残りませんて。苦笑。
見た目的にはCSSにてフッタであること事を分かり易くしているつもりなので、これらの見出しにはdisplay:noneを指定しています。CSSをオフにすると、フッタであることが分かりづらくなると同時に、フッタであることを示す見出しが登場すると言う寸法です。
ここで脱線します。foo bar bazの次が気になって仕方なくなってしまいました。調べたところどうもbuzを使っている人が多いようです。ではその次は……5つ目6つ目があったらどうすればよいのでしょうか。
[Tutor] what is foo bar? (英語)という質問を経由して、The New Hacker's Dictionary (英語)を見つけました。
foo, bar, bazのようなものをmetasyntactic variable (英語)というのだそうで、メタ構文変数? という意味なのでしょうか、良く分かりませんが、ともかく色々なバリエーションがあるようです。で、ざっと見る限り、この変数が幾つあっても恐れずに済むのがこのパターンです:
これで安心して眠ることが出来ます。quxはkwuhksと発音するのだそうです。ところでbuzはどこですか?
また気になることを思い出してしまいました。どうして日本(特にウェブ上)では、nullをヌルと言うのでしょうか。ナルと呼んでいた私はちょっとショックでした。ヌルって妙に不愉快なのですが。
「ヌル ナル」で検索すると恐ろしい罠が……(以下略)。
気を取り直して「ヌル、ナル、null」で検索しました。今度は成功です。情報処理用語正誤表を見つけました。ナルと書いてもほとんど無駄な抵抗に近い
のだそうです。
これも想像に過ぎないが、 null を最初に「ヌル」と書いた日本人は、ドイツ語のことが頭にあったのではなかろうか。ドイツ語にも null という語があり、英語の null とは同語源である。そしてそれは「ヌル」のように発音される。おそらく、そのことが頭にあって null を「ヌル」とカタカナ表記したものであろう。われわれは今後「ヌル」という語を使うとき、その起源がドイツ語にあることに思いを致さねばなるまい。
情報処理用語正誤表 より
そうなのかも知れませんが、やはり「ヌル」はどうしても嫌なのです。
変な発音というのは情報処理用語正誤表以外にも沢山あります。嫌なことを思い出しました。「ポジティブ」です。この発音は日本人の私には染み付いているんですよ。忘れやしません。某ネイティブにしつこく聞きなおされた挙句:
この野郎、と内心思いました。ジェスチャーは余計です。
ちなみに「パズティブ」の「ズ」と「ブ」は破擦音で、実際には母音は発音されません。「ブ」の母音を発音しなかったとしても微妙に違う気がします。というか、「ブ」の母音を発音しない場合、それは破裂音になりますから、やっぱり違うのです。追求するとキリがありませんが、兎も角「ポジティブ」は伝わらない(あるいは伝わらないフリをされる)とういことです。伝わらないフリをするのは日本語を良く知っている人で、わざとらしいのが特徴です。
あけましておめでとうございます。
去年(2002年)の記事を整理してみましたが、XPathなるカテゴリを作っていたことをすっかり忘れていました。何故そんなものを作ったのかと自分を問い詰めたい気分ですが、今更遅いので、無理矢理XPathの記事でも書いてみようと思います。
適当にXPath1.0を勉強すると、応用する際に困るのではないかと思います。
例を挙げます。
このような省略だらけの方法を覚えても、全然応用が効かないのです。「class属性を持ったp要素を特定するには、p[@class]と書けばよいのです。分かりやすいでしょう?」うんぬん。しかし、例えばこの例とは逆に、class属性を持たないp要素を指定することを考えてみて下さい。まったく別のことを覚えなければなりません。
述語[1]と[@class]について考えてみます。一体、[]の中身はどのようなデータ型になっているのでしょうか。1は数値だし、@classは、attribute::classの省略形で、軸とノードテストで構成されており、classという属性ノードを示しています。述語には、他にどのような型が許され、どのように解釈されるのでしょうか。茫然としませんか?
しかし、省略をせず、見た目の分かりやすさを諦めれば、述語内に記述が許される(実際には勝手に変換される)のはブール型であるということが一目で分かります。それさえ分かれば、応用の幅がぐんと広がるはずです。
上のXPath(ロケーションパス)は、まずルートノードとその子孫ノード全ての集合に焦点を合わせ、それら各ノードの子供の内、最初に登場するdiv要素に焦点を合わせ、それらの各div要素の子供の内、class属性を持っているp要素に焦点を合わせています。
一見分かり難いのですが、結局のところ、このような書式を理解できなければ殆ど応用が効かないのです。だったら最初からきちんと覚えるべきではありませんか? 一案としてはこの例のように、比較演算子を用いた式の形にしておくと良いのではないでしょうか。
意図せぬ「型変換」も予防しておきたいところです。例えば:
これは、'note'という文字列とclassという属性ノードを比較しているように見えますが、内部ではstring関数で型変換が行われています。キッチリ書くとこのようになります:
boolean関数、string関数の性質についてはXML Path Language (XPath) (英語) を参照して下さい。
「文書解析順に見て一つ目と二つ目のdiv要素の子供で、class属性を持たないp要素」は次のように指定できます。:
書き方は他にも考えつきますが、しかしどうでしょう。最初に挙げたような簡単な書式(//div[1]/p[@class])から連想できるでしょうか。私には無理です。それから、「 // 」は確実に意味が分かるまでは絶対に使うべきではありません。例えば//div[1]は、最初に登場するdiv要素ではありません。//でツリー上の全てのノードを指定し、そしてそれら全てのchild::軸を見ています。
因みに、XPathでより正確なノードリストを指定することができれば、XSLTスタイルシートを書く際の負担が激減します。特に構造化スタイルシートを書く際には死活問題で、XPath1.0を使いこなしてもまだ機能的に足りないくらいです。正規表現が使えないのはともかくとして、式によって返却されたノードリストは和集合しか取れない、コンテキストノードを操作できない、等々。position関数の出来の悪さには頭にきます。
DOMの文脈にてXPathを気軽に使えるよう、カスタムパネルJtrEntに操作用インターフェイスを組み込んでおきましたので、fub_netユーザな方は、色々試してみては如何でしょうか。
var xml = new JtrXML('http://www.w3.org/');
var doc = xml.getDocument();
これで変数docはhttp://www.w3.org(XHTML文書)のDocumentへの参照になり、かつ、XPathを使用するためのプロパティも設定が済みました。Document.selectNode(XPath)でノードリストを参照できます。
文書制作者が指定した名前空間接頭辞がそのまま使えますが、デフォルトの名前空間は、「defaultNS」を名前空間接頭辞にしてあります。http://www.w3.org(XHTML)の場合には、全ての要素はhttp://www.w3.org/1999/xhtmlという名前空間を(接頭辞無しで)もっていますから、ノードテスト(QNameです)には必ずdefaultNSという接頭辞をつけます。例示します:
var xml = new JtrXML("http://www.w3.org/");
var doc = xml.getDocument();
var sXPath = "/descendant::defaultNS:a[boolean(attribute::rel)]";
var nl = doc.selectNodes(sXPath);
rel属性を持ったa要素で構成されるノードリストを変数nlで参照しました(因みにこのa要素は10個見つかりました)。
つまらない例だな。
ではW3Cホームページの「ニュース記事」を保存してみましょう。マイ コンピュータ(謎)のセキュリティ設定を低くしているなら、保存用のsaveメソッドが使えます。インスタンスを生成することで、JtrXMLオブジェクトと、それから、Stringオブジェクトにも(笑)実装されますので手軽に使えます。
まずニュース記事を特定しましょう。
まあ普通に「ソース」を見ても良いのですが、私は正にこのためにDOM Inspectorを作ったのでして……。ともかく、これでニュース記事は「class="newsBlock"」という属性を持ったdiv要素でグループ化されていることが分かりました。[JScript]ボタンを押し、次のスクリプトを書きます。
var xml = new JtrXML("http://www.w3.org/");
var doc = xml.getDocument();
var sXPath = "/descendant::defaultNS:div[string(attribute::class) = 'newsBlock']";
var elmDiv = doc.selectSingleNode(sXPath);
これでニュース記事のdiv要素を変数elmDivで参照することができました。XMLソースはNodeインターフェイスのMS独自拡張、xmlプロパティで参照でき、Stringオブジェクトになっています。
var path = 'C:\\temp\\w3c_news.txt'
elmDiv.xml.save(path);
これで保存完了です。パスは適当(好い加減と言う意味ではない)なものにしてください。尚、saveメソッドは私による独自拡張(笑)なので気をつけてください。
と、このようにMIME typeの判別を代理人任せにしなければ、text/htmlでserveされていたとしてもXHTML文書はご立派なXML文書なのですよ(これが言いたかったんです実は)。Wired (英語)がXHTML+CSSでリニューアルされた時、私がどれだけ嬉しかったか分かっていただけるでしょうか。