2002年6月 - マーク付けノート

2002年06月02日

XMLXHTML

モジュール化された最近の XHTML だが、モジュールを適宜組合せたり、新しいモジュールを追加したりする事は、確かに出來る。しかし、それによつて生成される或種の文書仕樣は、決して XHTML の仕樣ではない。それは飽くまで XML の適用である。

XHTML ホスト文書型は text/xml や application/xml でサーブするより application/xhtml+xml でサーブする方が好ましい とのことなので、その意味では XHTML モジュールを(ホストとして)利用している文書類も、XML と見なすよりは XHTML と見なす方が適切であると思われます。

img の width と height

img 要素の width / height 属性は確かに物理属性ですが、同時に論理属性としての側面も持っています。ですから、いわゆる strict HTML 的に width / height の記述が好ましくない、などということはないと思います。

例えば a / area 要素の shape / coords 属性は物理属性ですが、同時に論理属性でもあるはずです。いくつかのパーツからなる画像があった場合、代替テキストなどはそれぞれのパーツに対応して記述されるべきですから、パーツの形状を記述する属性が定義されることは必然的ですし、また論理的であると思います。

この a / area の shape / coords は、img (あるいは object) の width / height に対応して記述されるものです。width="100" height="100" の img に対する shape="rect" coords="0, 0, 50, 50"width="200" height="200" の img に対する shape="rect" coords="0, 0, 50, 50" では全く意味が異なってしまう以上、shape / coords の定義されている(すなわち width / height が論理的な意味を持ちうる) HTML では、img の width / height を明示すべきと考えた方が良いと思います。

なお、img の width / height は「画像本来のサイズ」を上書きしますが、これは SVG のようにそもそも「画像本来のサイズ」というものを持たない可能性のある画像形式が存在する以上、当然であると思います。従って、これらの属性は「画像本来のサイズ」とは無関係に、HTML 文書の作者の意図するサイズとして記述すべきでしょう。

# というか、ISO-HTML の定義では「画像ファイル自体がサイズを持たない画像」に対するイメージマップを作成できなくなってしまうと思うのですが、これは不具合ではないのでしょうか。

2002年06月11日

コンテントネゴシエーション

<object data="/images/banner.svg" type="image/svg+xml" width="88" height="31">
 <img src="/images/banner.png" alt="bubble hour" width="88" height="31" />
</object>

以前、バナーを上記のようにマークアップしていたのだが、よく考えたらコンテントネゴシエーションを設定して img src="/images/banner" とでもすれば済む話なんじゃないかと思った。

ところで、こういう風にコンテントネゴシエーションを利用した URI に対するリンクを記述する場合には、当然メディア型は不定になってしまうと思うのだが、type (擬似)属性が必須である script 要素や xml-stylesheet 処理命令ではどのように type を記述すれば良いのだろう。

# 2003-11-10 追記

xml-stylesheet 処理命令の type 擬似属性は必須ではありません。これは Errata として修正されています。(Errata for REC-xml-stylesheet-19990629)

小さいということは便利である

HTML 4.01 準拠だと、半角 60 字が限界だろうか。多分それより小さくはできないはず。

# 2003-11-10 追記

<!DOCTYPE html PUBLIC"-//W3C//DTD HTML 4.01//EN"><title//<p> で 60 文字、と言いたかったんだそうです。

div と h1-h6 の入れ子の検証

見出しを含むセクションを div としてマーク付けされた XHTML 文書は、DTD では入れ子の正当性を検証できない という話ですが、実はトリッキーな方法を用いれば不可能ではありません(もっとも、「できるだけ」ですが)。

この定義では、XHTML の要素型セットを拡張することなく(ここ重要)、例えば「h2 を含む div」は「h1 を含む div」の直下にしか記述できないようにしてあります。

# 名前空間接頭辞というのはこういうことをするためにある訳ではありませんので。あくまで洒落です。念のため。

名前空間接頭辞と DTD

続いて、DTD は XML 名前空間と相性が悪いという話。これは確かにその通りで、実際これを知らないために「名前空間接頭辞の変更は DTD による検証に影響を及ぼさない(はず)」という誤解をしている人も(複数)見掛けたことがあります。

ただ、どんな場合であれ接頭辞を変更する場合には DTD に手を加える 必要があるのは確かであるものの、工夫さえすれば変更そのものは簡易に済ませることもできます。

例えば XHTML 1.1 や MathML 2.0 、SVG 1.1 などの DTD はモジュール化を念頭に置いて設計されていますから、接頭辞を変更するにもそれほどの手間は必要としません。

具体的に XHTML 1.1 plus MathML 2.0 plus SVG 1.1 DTD での例を挙げても、名前空間接頭辞の変更は次のような記述をするだけでかないます。

<!-- 文書型名(ルート要素型名)は適宜変更 -->
<!DOCTYPE xhtml:html
     PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"
            "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd" [

<!-- XHTML の要素で接頭辞を使用する場合は "INCLUDE" 、
     使用しない場合は "IGNORE" を指定 -->
<!ENTITY % XHTML.prefixed "INCLUDE" >

<!-- XHTML の接頭辞を指定(下の例では xhtml:p のようになる。
     上で "IGNORE" を指定した場合には省略してもよい) -->
<!ENTITY % XHTML.prefix "xhtml" >

<!-- 同様に SVG の接頭辞を設定 -->
<!ENTITY % SVG.prefixed "INCLUDE" >
<!ENTITY % SVG.prefix "svg" >

<!-- 同様に MathML の接頭辞を設定 -->
<!ENTITY % MATHML.prefixed "INCLUDE" >
<!ENTITY % MATHML.prefix "math" >
]>

要するに、一つの言語(要素型セット)に対して二つの宣言があれば事足りるようにはできる訳です。

# ただし、こういう方法では、ある要素型の接頭辞を場所によって変更したりすることは不可能で、やはりこの辺り DTD と XML 名前空間は相性が悪いと言わざるを得ません。はい。ここで言いたかったことは、「努力と根性である程度はカバーできる」という程度のことであります。

スキーマとしての XML DTD

まあ、XML の DTD がスキーマとして劣っているというのは、(XML という規格本体を小さなものにしようという)その制定理念から言って仕方のないことのような気もしますが。ただ、一般実体参照や属性の省略時値を設定してある場合、パーザは(型妥当性を検証するか否かに関わらず) DTD 全体をパーズせねばならない訳で、この辺りはどうにもすっきりしないものがあります。

XML DTD のスキーマ機能自体は、従来の SGML との互換性を保つために残された訳で、それはむしろ余り気にならないのですが。例えば「一般実体宣言は内部サブセットにのみ記述できる」「型妥当性を検証しないパーザは、属性の省略時値を #IMPLIED と見なす」というような制約があれば、XML DTD ももっと扱い易いものになったのではないかと思ったりします。

# こういう制約を設けておけば、例えば XHTML 1.1 の DTD を使用する際にも、次のように記述することによって standalone="yes" を宣言できるようにできたはず。多分。

<?xml version="1.0" encoding="UTF-8" standalone="yes">
<!DOCTYPE html
     PUBLIC "-//W3C//DTD XHTML 1.1//EN"
            "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" [
<!ENTITY % xhtml-charent.module "IGNORE" >
<!ENTITY % xhtml-charent.mod
     PUBLIC "-//W3C//ENTITIES XHTML Character Entities 1.0//EN"
            "xhtml-charent-1.mod" >
%xhtml-charent.mod;
]>

# 属性値の #FIXED がなければ、現行の XML でもこういうのを standalone="yes" してしまって良いのかなあ。どうも仕様書でのスタンドアロン宣言の定義というのは曖昧なような。僕の理解が浅いだけのような気もするが。

# 2003-11-10 追記

当時の standalone 宣言に対する理解が大分足りていないというか、ぶっちゃけ間違っているのでアレなんですが、前半は特に変なことは言っていません。後半(こういう制約を設けておけば〜以降)はでたらめですね。とりあえず要素内の空白文字の扱いを全く考慮していません。

2002年06月21日

更新履歴

DTD 中のシステム識別子を URI 形式で記述する場合には、常に絶対パスで記述するのが好ましいのではないか、という話。

2002年06月23日

文書の構造化 (1)

さて、XHTML を使うのは機械で処理しやすいように、という意見の人たちの話を見ていると、SECTION 要素については評価しても、DIVn 要素については評価していないように見受けられる。

文章の中で、見出しと、本文の内容は等価とみなされる。その等価である範囲が明示されていないと、機械で処理ってしづらいと思うのです。

Pre-HTML で言うところの div1-div6 ですが、要素型の定義そのものは評価していて、非常に有用だと思っています(実際利用しようかとも考えています)。

ただ、Pre-HTML のように section の明示なしに div1-div6 を用いるのでは、結局どの h2 とどの div2 が関連しているのかということを簡単には判断できません。ですから、div1-div6 を用いるのであれば、section も明示しないと利用価値が半減してしまうと思うのです。

章のマーク付けの仕方と、それに対して想定可能な利用方法は、概ね次のようになると考えています。

section > (h1-h6, div1-div6) で扱える範囲
  • 一対の見出しと本文からなる「章」の全体
  • 特定の章の本文に対する「見出し」
  • 特定の章の見出しに対する「本文」
section > (h1-h6, (%Block.mix;)+) で扱える範囲
  • 一対の見出しと本文からなる「章」の全体
  • 特定の章の本文に対する「見出し」
  • # 特定の章に対する「本文」だけを扱うことは想定しない
(h1-h6, div1-div6)+ で扱える範囲
  • (どの本文に対応する見出しかという)関連付けは想定しない「見出し」
  • (どの見出しに対応する本文かという)関連付けは想定しない「本文」
  • # 特定の見出しと本文とを関連付けて「章」として扱うことは想定しない

このことを踏まえて、「特定の章(=見出し+本文)」「特定の章の本文に対する見出しのみ」を抽出したい場合はあっても「特定の章から見出しを除いた本文のみ」を抽出したい場合というのは余りないのではないか、と考えた結果が、現状の div-div6 を用いないマーク付けになっています。

ただ、最近「やはり div1-div6 も必要じゃないかな」という方向に考えが変わってきておりまして、マーク付けを変更しようかとも思っています。

正直なところ、以前は section と div1-div6 を両方明示するというのは過度なマーク付けなんじゃないかという印象があって、現状のマーク付けにはその印象がかなり影響しています。しかしながら、定義リストなどを例に取って考えた場合、やはり dl (section に相当)も dt (h1-h6 に相当)も dd (div1-div6 に相当)も、どのマーク付けも冗長なものではないと思いますし、むしろ必然的なものであると思います。

ということで、XHTML 2.0 では div1-div6 相当の要素型の導入もあってよいのではないかということも考えたりしています。

# ただし、現状はまだ自分自身この問題についての判断を決定していません。ここで述べた意見も近い将来修正される可能性があります。

文書の構造化 (2)

ところで、W3C は W3C XML Specification DTD (-//W3C//DTD Specification V2.1//EN) という仕様書用の DTD を公開していて、この中で div1-div5 という名前を「見出しを含めた章(つまり XHTML 2.0 の section 相当)」を表す要素に対して用いているんですよね。紛らわしいので、どちらかに統一するか他の名前を付けるかして欲しいんですが。

2002年06月27日

XMLP

XML Transfer Protocol ではないらしい。ちなみに中身はまだ読んでません。

次世代の XHTML についての私案

あくまで私案です。念のため。

セクション/見出しなどの基本構造は、概ね次のような感じ。

<sec>
 <shead>
  <h>Heading</h>
  <link rel="..." xlink:href="...">...</link>
  <link rel="..." xlink:href="...">...</link>
  <meta name="...">...</meta>
  <meta name="...">...</meta>
 </shead>
 <sbody>
  <abs>
   <p>Abstract of this section.</p>
  </abs>
  <sec>...</sec>
  <sec>...</sec>
 </sbody>
</sec>

この構造で、sec を html に、shead を head に、sbody を body に、h を title に置き換えてやると、一個の文書は全てのレベルで統一的な構造を持てる。ただ、head/body/title はともかく、セクションを html や doc と言った要素名で表現するのは今ひとつしっくりこない気がするが。ルートの要素を sec にしてしまう手もあるが、やはり html 要素は html 要素のままの方が無難のような気もする。

文書全体は次のようになる。

<?xml version="1.0" encoding="UTF-8" ?>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://www.w3.org/1999/xhtml"
      xmlns:xlink="http://www.w3.org/1999/xlink"
      xml:lang="ja" >
 <head>
  <title>文書のタイトル</title>
  <!-- *文書全体* に関連するリンク -->
  <link rel="..." xlink:href="...">...</link>
  <link rel="..." xlink:href="...">...</link>
  <!-- *文書全体* についてのメタ -->
  <meta name="...">...</meta>
  <meta name="...">...</meta>
 </head>
 <body>
  <sec>
   <shead>
    <h>セクションの見出し</h>
    <!-- *このセクション* に関連するリンク -->
    <link rel="..." xlink:href="...">...</link>
    <link rel="..." xlink:href="...">...</link>
    <!-- *このセクション* についてのメタ -->
    <meta name="...">...</meta>
    <meta name="...">...</meta>
   </shead>
   <sbody>
    <abs>
     <p>このセクションの要約</p>
    </abs>
    <!-- さらに下位のセクション(または直接ブロック要素の列による本文) -->
    <sec>...</sec>
    <sec>...</sec>
   </sbody>
  </sec>
 </body>
</html>一応、この名前での文書型定義を。

<!ELEMENT body (sec+ | (%Block.mix;)+) >
<!ELEMENT sec (shead, sbody) >
<!ELEMENT shead (h, link*, meta*) >
<!ELEMENT sbody ((abs?, sec+) | (%Block.mix;)+) >
<!-- abs と %Block.mix; が並列になることは通常有り得ないと思うので
     こういう内容モデルにしたけど、実際のところどうだろう? -->

<!ELEMENT abs (%Block.mix;)+ >

html/sec 以外、head/shead 、body/sbody 、title/h などの要素名を統一した場合の文書型定義は次のような感じ。

<!ELEMENT html (body, head) >
<!ELEMENT sec (head, body) >
<!ELEMENT body ((abs?, sec+) | (%Block.mix;)+) >
<!ELEMENT head (title, link*, meta*) >
<!ELEMENT abs (%Block.mix;)+ >

html と sec には属性の違いなどもあるので、この定義は実は過不足なく良い感じにまとまっているかも知れない。ただし、ユーザエクスペリエンス的にどうか、という気はするが。この場合、文書全体は次のようになる。

<?xml version="1.0" encoding="UTF-8" ?>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://www.w3.org/1999/xhtml"
      xmlns:xlink="http://www.w3.org/1999/xlink"
      xml:lang="ja" >
 <head>
  <title>文書のタイトル</title>
  <!-- *文書全体* に関連するリンク -->
  <link rel="..." xlink:href="...">...</link>
  <link rel="..." xlink:href="...">...</link>
  <!-- *文書全体* についてのメタ -->
  <meta name="...">...</meta>
  <meta name="...">...</meta>
 </head>
 <body>
  <sec>
   <head>
    <title>セクションの題名</title>
    <!-- *このセクション* に関連するリンク -->
    <link rel="..." xlink:href="...">...</link>
    <link rel="..." xlink:href="...">...</link>
    <!-- *このセクション* についてのメタ -->
    <meta name="...">...</meta>
    <meta name="...">...</meta>
   </head>
   <body>
    <abs>
     <p>このセクションの要約</p>
    </abs>
    <!-- さらに下位のセクション(または直接ブロック要素の列による本文) -->
    <sec>...</sec>
    <sec>...</sec>
   </body>
  </sec>
 </body>
</html>

…という感じでざっと列挙したが、何でこういうことを考えたのかという過程を述べないと意味がない気がしてきた。一応理由があってこういう案に至ったのだが。その辺はまた後日。

2002年06月29日

パラメタ実体参照と整形式制約

実体参照宣言が出現する前に実体参照が存在すると、「未定義の実体参照」と見倣してしまいます。例えば、以下のような例は、仕様上は問題ありませんが、 MSIE 上ではエラーとなります。この不具合は、「XHTML 1.1/Basic 準拠の文書が MSIE で表示できない」問題として有名です。

<!ELEMENT %element.qname; EMPTY>
<!ENTITY % element.qname "element">

この記述は整形式制約を満たすので、その意味では確かに仕様上問題ないのですが、妥当性制約は満たしません ([VC: Entity Declared] The declaration of a parameter entity must precede any reference to it.)。XHTML 1.1/Basic は妥当性制約を満たすように設計されているので、「XHTML 1.1/Basic 準拠の文書が IE で表示できない」のは、この実装のせいではなかったと思います。

ちなみに、XML 1.0 の初版では、前述の The declaration of a parameter entity must precede any reference to it. という文言が整形式制約として記述されていました(誤りとして第二版では削除)。その意味では、開発時期を鑑みれば IE の実装も致し方ないように思います。

IE に XHTML 1.1 をパージングさせる

2003-12-12 追記
以下の記事は、書き直して「MSXML に XHTML 1.1 を解析させる」にまとめました。

上の記事に関連して。僕の記憶か確かならば、WinIE が XHTML 1.1 のパージング中にエラーを吐く原因は以下の三つだったと思います(半年前に試したきりなのでうろ覚えですが)。

IGNORE 区間中のパラメタ実体参照を展開しようとする

多分これが一番有名なバグで、%xhtml-prefw-redecl.mod;%xhtml-postfw-redecl.mod; を展開しようとしてエラーになります。このバグは、例えば次のようにそれぞれの実体を宣言することで対処できます。

<!ENTITY % xhtml-prefw-redecl.mod "" >
<!ENTITY % xhtml-postfw-redecl.mod "" >
どこかのモジュールの(相対 URI による)システム識別子を正しく補完できない

この問題は、IE のバージョンによっては生じなかったかも知れません。文書型宣言のシステム識別子を、フラット DTD のもの (http://www.w3.org/TR/xhtml11/DTD/xhtml11-flat.dtd) に書き換えることで対処できます。

内容モデルを定義するパラメタ実体値中、%foo.qname;? %foo.qname;* %foo.qname;+ という形の記述があるとエラーになる

%foo.qname; の実体は foo で宣言されているので、本来 (%foo.qname;+|%hoge.qname;) のような記述は (foo+|hoge) という記述と等価であると見なされることになっています(従ってこの記述は整形式)。ところが、IE 5.x? はこういう記述を正しく処理できません。

該当する箇所 (table と ruby の内容モデル)に対し、次のように括弧を追加してやれば対処できます。

<!ENTITY % table.content
     "( (%caption.qname;)?, ( (%col.qname;)* | (%colgroup.qname;)* ),
      (( (%thead.qname;)?, (%tfoot.qname;)?, (%tbody.qname;)+ )
      | ( (%tr.qname;)+ )))"
>
<!ENTITY % Ruby.content.complex 
     "| ( %rbc.qname;, %rtc.qname;, (%rtc.qname;)? )"
>

結局、IE に対し、XHTML 1.1 の文書を XML としてパージングさせるためには、文書型宣言を次のようにしてやる必要があります。

<!DOCTYPE html
     PUBLIC "-//W3C//DTD XHTML 1.1//EN"
            "http://www.w3.org/TR/xhtml11/DTD/xhtml11-flat.dtd" [
<!ENTITY % xhtml-prefw-redecl.mod "" >
<!ENTITY % xhtml-postfw-redecl.mod "" >

<!ENTITY % table.content
     "( (&#37;caption.qname;)?, ( (&#37;col.qname;)* | (&#37;colgroup.qname;)* ),
      (( (&#37;thead.qname;)?, (&#37;tfoot.qname;)?, (&#37;tbody.qname;)+ )
      | ( (&#37;tr.qname;)+ )))" >
<!ENTITY % Ruby.content.complex 
     "| ( &#37;rbc.qname;, &#37;rtc.qname;, (&#37;rtc.qname;)? )" >
]>

こうすれば、text/xml や application/xml でも XHTML 1.1 の文書を正しく扱えたはずです。確か。一応、以下サンプル。

この文書のステータス

URI
http://www.satoshii.org/markup/notes/2002/06
初版
2002-06-02
最終更新
2003-12-12
著者
石川哲志
Copyright © 2002-2003 Satoshi ISHIKAWA, All Rights Reserved.