SXML

このページは SXML revision 3.0 の仕様を定める。 SXML は XML 文書の抽象構文木であり、 XML Infoset の S 式による具象表現でもある。 SXML は、一般的な木構造をしていることにより、 問い合わせ、変換用のコンパクトなコンビネーターライブラリを備えることができた。

SXML の仕様書の原本はそれ自体 SXML で書かれている。 この Web ページはその SXML コードを適当な「スタイルシート」で 変換したものである。 もとの SXML ファイルと、HTML やその他の形式に変換したもの、 変換用のスタイルシートは <http://pobox.com/~oleg/ftp/Scheme/xml.html> に置いてある。

  1. はじめに
  2. 記法
  3. 文法
  4. 注釈
  5. SXML ツリー
  6. 名前空間
  7. SXML における名前の大文字小文字の別
  8. 正規化 SXML
  9. Acknowledgment
  10. 参考文献
  11. 前の版からの変更点

はじめに

XML 文書は本質的に木構造である。 ルート要素の開始タグと終了タグは文書の内容を包含し、 文書の内容部はほかの要素や任意の文字データを含む。 よく見る角括弧をつかったテキストは XML 文書の外部表現である。 アプリケーションはこれを内部形式 ―― XML Information Set もしくは、それを目的に特化したもの―― に変換してあつかうはずである。 こうすることにより、アプリケーションは特定のデータを検索したり、 XML 文書の木をほかの木構造に変換し XML や HTML、PDF といった文書として書き出すことができるようになる。

XML Information Set (Infoset) [XML Infoset] は well-formed な XML文書で利用可能な情報を表現する抽象データ型である。 Infoset は「情報項目」から成り、情報項目は要素、属性、文字データ、 処理命令その他の文書の内容物を表現する。 それぞれの情報項目には対応する特性がいくつもある。 例えば、名前、名前空間、URI などである。 また、ある特性、例えば「子」や「属性」などは他の情報項目の集合である。 Infoset はアプリケーションに関係のある XML 文書の情報だけを記述し、 DTD で指定した属性のデフォルト値や、パラメータ実体、 開始タグ内の属性の順序、単純に構文解析や妥当性検査の際に使われるだけの 情報といったものには関知しない。 技術的には、Infoset は XML 向けに定められたものであるが、 特に HTML のような、半構造化されたデータ形式にも広く適用することができる。

テキスト列やほかのコンテナを内に含むコンテナの階層構造というのは S 式で表現するのに非常によく向いている。 S 式 [McCarthy] は構文解析して走査向きの構造を簡単に得ることができ、 (括弧がたくさんありはするが)手書きでも比較的簡単に書くことのできる 単純な外部表現がある。 また、S 式には別の利点もある。 適切な設計があたえられていれば、評価可能な Scheme コードで表現できるのだ。 このコードとデータの二元性は Lisp と Scheme の優れた特徴である。

SXML は XML Infoset の具象表現である。 Infoset の目標は、すべての関連するデータと、 それらの抽象的なコンテナ-スロット間の関係を 何らかの形式で表現することである。 SXML では、コンテナの入れ子に S 式としての明確な実現をあたえ、 項目やその特性にアクセスする手段を提供した。 SXML は XPath [XPath] や DOM [DOM] の「仲間」である。このふたつのデータモデルは XML Infoset の別の表現型である。 SXML は特に、Scheme ベースの XML/HTML 製作、SXPath クエリ、木構造変換に 適したものになっている。 John Hughes の用語集 [Hughes-PP] では、SXML は XML 文書の評価実装を指す言葉になっている。

記法

我々は XML 勧告 [XML] で採用されている拡張 BNF 記法をつかうことにする。 以下に表記の概要を示す。

thing?
省略可能な thing
thing*
0 個以上の thing
thing+
1 個以上の thing
thing1 | thing2 | thing3
thing1, thing2……のいずれか
<thing>
非終端要素
thing
終端要素で Scheme の識別子であるもの
"thing"
終端要素で Scheme の文字列であるもの
thing
Scheme のリテラルシンボル
( <A> <B>* <C>? )
S 式で、<A> のあとに 0 個以上の <B> がつづき、そのあとに省略可能な <C> がつづくようなもの
{A <B>* }
タグ付き集合。S 式で、A のあとに 0 個以上の <B> のインスタンスが任意の順序でならんだもの
( <A> . <B> )
S 式 <B> の前に <A> をつけてつくられた S 式
make-symbol(<A>:<B>)
文字列表現が、<A>:<B> であるようなシンボル。make-symbol() はシンボルをつくるメタ関数と見ることもできる。

文法

[1]  <TOP> ::= ( *TOP* <annotations>? <PI>* <comment>* <Element> )

SXML ツリーの根を表現する。 Infoset で言う文書情報項目である。 この要素の唯一の子要素は XML 文書のルート要素である。

[2]  <Element> ::= ( <name> <annot-attributes>? <child-of-element>* )
[3]  <annot-attributes> ::= {@ <attribute>* <annotations>? }
[4]  <attribute> ::= ( <name> "value"? <annotations>? )
[5]  <child-of-element> ::= <Element> | "character data" | <PI> | <comment> | <entity>

SXML の基本的な構成要素である。

[6]  <PI> ::= ( *PI* pi-target <annotations>? "processing instruction content string" )

XML 勧告では処理命令(PI)は要素や文字データと明確に区別できると 規定されている。処理命令はアプリケーションに直接渡らなければならない。 SXML では PI は *PI* で特定されるノードで表現する。 DOM Level 2 も同様の方法で処理命令をあつかっている。

[7]  <comment> ::= ( *COMMENT* "comment string" )
[8]  <entity> ::= ( *ENTITY* "public-id" "system-id" )

完全性のためにコメントにも触れておく。 SSAX XML Parser [SSAX] は、 他の構文解析器と同様にコメントを透過的に読み飛ばす。 XML 勧告では、構文解析器がコメントをアプリケーションにそのまま渡すことも、 まったく無視してしまうことも両方を認めている。 現在の SXML の文法ではコメントノードの存在を認めているが、 それに何の意味も持たせていない。

<entity> ノードは展開されない外部実体への参照を表現する。 このノードは [XML Infoset] の 2.5 節に定義された非展開外部実体情報項目にあたる。 内部的には、解析された実体は常に文書内で参照されたところですぐに XML 処理系に展開される。

[9]  <name> ::= <LocalName> | <ExpName>
[10]  <LocalName> ::= NCName
[11]  <ExpName> ::= make-symbol(<namespace-id>:<LocalName>)
[12]  <namespace-id> ::= make-symbol("URI") | user-ns-shortcut
[13]  <namespaces> ::= {*NAMESPACES* <namespace-assoc>* }
[14]  <namespace-assoc> ::= ( <namespace-id> "URI" original-prefix? )

SXML の <name> は単一のシンボルである。 これは一般に展開名[XML-Namespaces]であり、 局所名と名前空間 URI から成る。 名前空間 URI は空の場合もあり、その場合 <name>NCName になり、XML 名前空間勧告 [XML-Namespaces] の生成規則 [4] の文字列表現に合致したシンボルになる。 <ExpName> もまた Scheme のシンボルであり、その文字列表現は名前の局所部分と名前空間部分を連結する コロンを含む。make-symbol("URI") により、名前空間 URI 文字列が Scheme のシンボルに変換される。 URI は(括弧のような) Scheme の識別子として認められない文字を含むことがある。 そのような文字は URI 文字列から <namespace-id> に変換するときに %XX 形式に変換しなければならない。 QName [XML-Namespaces] のもともとの名前空間接頭辞は、<namespace-assoc> の省略可能な original-prefix メンバーとして保存されることがある。 user-ns-shortcut はアプリケーションプログラムが名前空間 URI をあらわすのに使うよう、 プログラマが選んだ Scheme シンボルである。 SSAX Parser では、多くの場合長過ぎて扱いにくい名前空間 URI に、(短かくてわかりやすい)固有の別名を定義できるようにしている。

注釈

[15]  <annotations> ::= {@ <namespaces>? <annotation>* }
[16]  <annotation> ::=   To be defined in the future

XML 勧告やそれに関連した標準は完全に固定したものではない。 これは XML version 1.1 の長大なエラッタからも明白である。 そのため SXML は、後方互換性を保ちつつ将来の変更に対応できなければならない。 また、アプリケーションが(解決済みの IDREF 等)さまざまな処理情報を SXML ツリー中に保存できるようにもすべきである。 例えば、ID 型の属性のハッシュをつかえば(SOAP 形式で)コード化された 配列の探索を効率良く実装できる。 このような拡張性を実現するために、我々は <annotations><annotation> という新たなノード型を導入した。

<annotation> の構造と意味論は属性リストと同じである。 注釈は言わば属性リストの「属性」である。 @ タグは SXML ノードの付加情報を示す。 要素ノードではこれは属性であり、入れ子になった @ リストは「二次的な」属性、つまり注釈である。 ここには名前空間ノードや親ノードへのボインタなどが含まれる。 この設計は、属性を別々のふたつの目的につかっている XML 勧告の信念にも合致すると思う。 本来属性は対応する XML 要素の付加情報を提供するものである。

     <weight units='kg'>16</weight>

一方で xmlnsxml:prefixxml:langxml:space といった属性は補助的に、もしくは XML 自身のために使われている。 XML 勧告では補助属性を xml という接頭辞で区別している。 SXML は、そういった属性をすべて @ でタグづけして、属性リストのなかに集めておくことにした。

XML で属性はごみ箱のようにあつかわれている。 例えば XSLT 勧告では xslt:template に XSLT 名前空間にない余分な属性をつけることを認めている。 したがって、利用者はこれをつかって XSLT テンプレートに自分の好きな属性で注釈をつけることができ、 また、XSLT 処理系はこの属性を見ず、これを黙って無視して処理をする。 RELAX/NG では、追加属性を特定の名前空間に所属させるようにさせ、 ある要素が追加の属性を持つことをスキーマの製作者に 明示的に指定させるようにしている。 このような追加属性があっても、仕様上この属性を見ない XML 処理アプリケーションには影響を与えないべきである。 親ノードへのポインタやソース上での位置情報のような注釈は、 ほとんど特定のアプリケーション向けと言ってもよい。 それ以外のアプリケーションは注釈の有無に左右されるべきではない。 注釈を属性リストに収めてしまえばこういった目標が達成されるのである。

注釈は要素にも要素の属性にもつけることができる。 以下の例では要素への注釈と属性への注釈のちがいを示す。 ここでは例として、注釈として親ノードへのポインタだけをもつものを挙げる。

     (a (@ 
          (href "http://somewhere/" 
            (@ (*parent* a-node))       ; 属性 href への注釈
            )
          (@ (*parent* a-parent-node))) ; 要素 a への注釈
        "link")

<TOP> ノードにも注釈をつけることができる。 たとえば、文書全体の名前空間や ID 型の属性の索引などである。

     (*TOP* (@ (id-collection id-hash)) (p (@ (id "id1")) "par1"))

<TOP> 要素の属性は、そのまま要素の属性のようにも見えるが、 これを混同すべきではない。 <TOP> 要素は属性を持てないものだからである。 SXML の <TOP> 要素は文書全体の抽象表現であり、 単一の XML 要素に対応するものではない。 属性リストのように見える注釈を <TOP> 要素につけるのは Infoset の勧告に何ら矛盾するものではない。 勧告はそれ自体網羅性を目指すものではないと述べられている。 属性一般は、親要素の子とは見做されない。 したがって、注釈をつけたとしても、<TOP> の子はルート要素ただひとつである。

SXML ツリー

Infoset の情報項目はその属性の総和である。 これにより、リストが項目を表現するのに特に適したデータ構造になっている。 リストの先頭の Scheme の識別子が項目に名前をつける。 多くの項目にとって、これはそれぞれの(展開)名である。 XML の要素をあらわす情報項目では、対応するリストは要素の展開名で始まり、 以下省略可能な属性と注釈がつづく。 残りの部分はその要素の子の列である。 子には、文字データ、処理命令他の要素がある。 個々の子は一意的である。 すなわち、ある要素が他と同一の内容だったとしても 子要素を共有することは決してない。

Infoset 情報項目の parent 特性は面倒なものに見えるかもしれない。 Infoset 勧告 [XML Infoset] では、要素、属性、その他の情報項目は parent という特性を持ち、その特性は、与えられた情報項目を children 特性として持つ項目を値として持つ、と規定されている。 すなわち、parent 特性は子から親への上向きのリンクである。 一見すると S 式はこのようなことを考慮していないように見える。 S 式は有向木を表現し、木は上向きのリンクを持つことができない、 ということである。 [Parent-pointers] では SXML ノードの親要素を特定するいつつの方法を比較している。 このような方法の存在は、SXML が XML Information set の完全なモデルであり、SXML 問い合わせ言語(SXPath)が XPath 勧告を完全に実装できることを構成的に証明するにあたって重要なことである。

Infoset 仕様が明示的に認めてい、XPath がしているように、 我々は文字情報項目を最大テキスト列にまとめている。 属性の値は一般に文字列である。 ただし、(HTML の場合)真理値属性の値は省略できる (例: <option checked>)。

我々は属性の集合をそれ自体情報項目として考え、@ でタグ付けすることにした。 「@」は正当な XML の名前としては現れない文字である。 したがって、<annot-attributes> は要素を表現するリストとして間違ってあらわれることはない。 XML 文書では、属性、処理命令、名前空間指定等々のメタデータは 要素とことなった表現をされる。 それに対して、SXML では要素もメタデータも統一的にタグ付きリストで表現される。 RELAX-NG もできるかぎり属性を要素と統一的に扱うようにしている。 このように統一的にあつかう方法は James Clark を納得させ [RNG-Design]、また、RELAX-NG を単純化するのに大きく貢献している。 SXML は、XML の名前はつねに Scheme の正当なシンボルであり、Scheme のシンボルのすべてが正当な XML の名前ではない、ということを利用している。 これにより、潜在的な名前の衝突の可能性を気にせずに @*PI**NAMESPACES* といった名前を導入することができる。 また、XML と SXML の関係を明確にすることもできる。 SXML に変換した XML 文書は(Infoset レベルで)等価な XML 文書に再構成することができる。 それだけでなく、Infoset の仕様により、SXML 自体が Infoset のインスタンスでもある。

SXML 文書は本質的に木構造であるため、3 節の SXML の文法は以下のように、より統一的に表現できる。

[N]  <Node> ::= <Element> | <annot-attributes> | <attribute> | "character data: text string" | <namespaces> | <TOP> | <PI> | <comment> | <entity> | <annotations> | <annotation>

または、NodeNodelist という相互再帰データ型をつかって以下のように表現することもできる。 Nodelist はノードのリストである。

[N1]  <Node> ::= ( <name> . <Nodelist> ) | "text string"
[N2]  <Nodelist> ::= ( <Node>* )
[N3]  <name> ::= <LocalName> | <ExpName> | @ | *TOP* | *PI* | *COMMENT* | *ENTITY* | *NAMESPACES*

要素、属性、処理命令を統一的に表現することで問い合わせや変換を単純化できた。 我々の定式化では属性や処理命令は特別な名前をもった普通の要素に見えるように なっている。 この結果、属性専用の問い合わせや変換用の関数といったものは不要になる。

Scheme の関数型 XML 解析フレームワーク SSAX [SSAX] の SSAX:XML->SXML 関数は XML 文書や well-formed な部分文書を対応する SXML 形式に変換することができる。 この解析器は、名前空間、文字・解析済み実体、属性値の正規化、処理命令、 CDATA セクションをサポートしている。

名前空間

XML Namespace の動機は James Clark の素晴しい論文 [Clark1999] に述べられている。 一部を引用する。

XML Namespaces 勧告では、要素型と属性の名前を URI で修飾できるようにデータモデルを拡張してこの状況の改善をこころみる。 こうすることで、車のパーツについて記述する文書ではある URI で修飾された part をつかい、 本の分冊について記述する文書では別の URI で修飾された part をつかうことができる。 局所名と URI 修飾部分を合わせて普遍名と呼ぶ。 普遍名における URI は純粋にアプリケーションがその名前を識別するためだけにあり、URI の指すリソースには何の補償もしない。 XML Namespaces 勧告では要素型や属性の名前が普遍名であることを求めず、 局所名であってもかまわないとしている。

...

XML Namespaces 勧告では XML 1.0 と互換性のある、間接的な方法で普遍名を表現する。 勧告では、要素型と属性の名前が局所名であるようなツリーから、 普遍名をつかったツリーへの写像を定義している。 この写像は接頭辞の考え方にもとづいている。 要素型や属性の名前にコロンが含まれていた場合、 コロンの前の部分を接頭辞と見做し、後ろの部分を局所名と見做す。 接頭辞 fooxmlns:foo の値で指定された URI を参照する。したがって、

     <cars:part xmlns:cars='http://www.cars.com/xml'/>

は以下に変換される。

     <{http://www.cars.com/xml}part/>

xmlns:cars は写像によって取り除かれることに注意。

James Clark の用語をつかえば、[N1] で定義された SXML は要素型や属性の名前が普遍名になりうるツリーである。 生成規則 [N3] と [9-12] によれば、普遍名 <name> は、局所名か展開名のどちらかである。 展開名は最低ひとつのコロンを含んでいる。 これにより識別子がすこし奇妙に見えるかもしれない。 SXML では James Clark の例は以下のようになる。

     (http://www.cars.com/xml:part)

もしくは、より冗長に次のように書くこともできる。

     (http://www.cars.com/xml:part
       (@ (@ (*NAMESPACES* (http://www.cars.com/xml "http://www.cars.com/xml" cars)))))

このような表現は Namespace の勧告 [XML-Namespaces] にも合致している。 曰く、接頭辞は名前空間名の代替物に過ぎない。 アプリケーションは、包含する文書を越えてつかわれる名前をつくるのに 接頭辞でなく名前空間名をつかうべきである。云々。

http://www.cars.com/xml:part のような識別子をつかうのは不格好だと思われるかもしれない。 そのため、SSAX parser を使うアプリケーションは http://www.cars.com/xml:part という URI に、c のようなアプリケーション独自の名前空間の短縮形 user-ns-shortcut を指定することができる。 そうすると、解析器は以下のような S 式を返す。

     (c:part (@ (@ (*NAMESPACES* (c "http://www.cars.com/xml")))))

より正確に言うと、ただ

     (c:part)

を返す。 アプリケーションが解析器に http://www.cars.com/xml の対応づけを指定したのなら、アプリケーションは対応関係を記憶していて、 別の注記は必要ないのである。

また、我々は http://www.cars.com/xml:part のような SXML ノード名を恐れなくてもよい。これは Scheme のシンボルである。 シンボル名がどれだけ長かったとしても、シンボルテーブルには一度しか 書き込まれない。 それ以外のシンボルはシンボルテーブルの対応するスロットへの参照になるのだ。

user-ns-shortcut と対応する名前空間 URI 群は一対一対応していなければならないことにも注意しておく。 user-ns-shortcut はドキュメント中の対応する名前空間 URI を一意的に表現するが、XML の名前空間接頭辞はそうではない。 たとえば、異なる XML 接頭辞が同じ名前空間 URI を指すこともあるし、名前空間接頭辞が子要素で再定義されることもある。 user-ns-shortcut と XML 名前空間接頭辞の違いは、 後者は文書の作成者の気まぐれで決められるもので、 前者は XML 処理アプリケーションが定義するということである。 user-ns-shortcut は名前空間 URI の構文糖衣である。

名前空間識別子と名前空間 URI の対応関係(と省略可能な、もとの XML 名前空間接頭辞)のリストは <annotations> の省略可能な項目である。 ふつうの要素では、<namespaces> は、その要素に関連する名前空間宣言だけを含むが、 ほとんどの場合、<annotations> 以下の <namespaces> 自体が存在しない。

<namespaces> ノードは、<TOP> 要素の注釈として現れた場合には、文書全体に対する <namespace-assoc> を含まなければならない。 もとの XML 文書ではひとつの名前空間 URI が複数の名前空間接頭辞と対応しているかもしれない。 このような場合、それに合わせて original-prefix だけが異なる <namespace-assoc> が複数できることになる。

(S)XML と (S)XPath での名前空間についての話題は [Lisovsky-NS] と [SXML-NS] で論じられている。

SXML における名前の大文字小文字の別

XML は大文字小文字を区別する言語である。 要素、属性、処理命令の対象等々の名前は大文字小文字の別だけで 別のものと見做されることもある。 SXML ではこのような名前も Scheme の識別子として表現される。 Scheme は伝統的に大文字小文字を区別しない言語であるが、 Scheme のシンボルをつかって XML の名前を表現しても何の矛盾も起こらない。 R5RS [R5RS] にはこうある。

(string->symbol symbol) は symbol の名前を文字列として返す。 symbol がリテラル式や read 関数の戻り値であれば、 ここで返る文字列は大文字か小文字うち、実装系の選んだ方の文字から成る。 これは、ある実装系では大文字であるかもしれないし、 別の実装系では小文字であるかもしれない。 symbol が string->symbol の返したものであれば、 文字列中の大文字小文字は string->symbol に渡した文字列と同じになる。

つまり、R5RS は明示的にシンボルの大文字小文字の別を認めているのである。 すなわち (string->symbol "a") は常に (string->symbol "A") とは異なる。 SXML ではこのような大文字小文字を区別するシンボルを XML の名前すべてに使用する。 SXML に準拠した XML 解析器は、名前をシンボルに変換するときに 大文字小文字の別を保存しなければならない。 解析器は R5RS の string->symbol 手続きをつかってもよいし、ほかの方法をつかってもよい。

SXML 文書の読み書きには特別の注意が必要になるかもしれない。 引用した R5RS の節では Scheme システムがリテラル式や入力ポートから読み込んだ シンボルの大文字小文字を変換することを認めている。 大文字小文字を区別しないシステムに SXML の名前を入力するには縦棒表記や string->symbol、 ないしはその他の非標準の方法を使わなければならない。 SSAX の組み込みのテストスィートは、大文字小文字の別のある SXML の名前リテラルを入力する非常に可搬的な方法の例である。 このような回避策は、単純ではあるが、DSSSL をサポートする Scheme 処理系には必要のないものである。DSSSL 標準に曰く、

7.3.1 大文字小文字の別。文字の大文字小文字はつねに区別される。 注 5: 伝統的に Lisp システムは大文字小文字を区別しない。

加えて、非常に多くの Scheme システムが大文字小文字を区別する読み込み器を持ち、コンパイラオプションや pragma でこれを有効にすることができるようになっている。 [Scheme-case-sensitivity] という Web ページでは様々な Scheme システムの大文字小文字の区別について議論している。

正規化 SXML

正規化 SXML は処理の効率化のために最適化された SXML の真部分集合である。 正規化された SXML 文書はいくつか追加の制約を満たさなければならない。 制約のほとんどは、生成規則 [2-4] にある <Element> 内の <annot-attributes><annotations> の有無や順序である。 リレーショナルデータベースの考え方を借りて、我々は SXML に段階的に厳格になる正規形を導入する。 M < N なる M, N について、第 N 正規形である SXML 文書は第 M 正規形でもある。 より高位の正規形では SXML 表現の構造上の制約は強くなるが、そのかわりにアクセスが高速化される。

第零正規形はもっとも寛容で、SXML 文法のたゆみと考えることもできる。 属性リストは、もし存在するなら、<child-of-element> のなかに交じってあらわれてもかまわない。 SGML では論理型属性に短縮形 <OPTION checked> と完全形 <OPTION checked="checked"> のふたつの記法がある。 HTML は両方を認め、完全形を推奨しているが、XML は後者しかみとめていない。 第零正規形は完全形に加えて省略形もサポートしてい、 (OPTION (@ (checked)))(OPTION (@ (checked "checked"))) も認められる。

第一正規形では、省略可能な <annot-attributes> が存在する場合、<Element> のほかの要素すべてより先に現れなければならない。 これは、生成規則 [2] の順序にも反映されている。 論理値属性は完全形 (OPTION (@ (checked "checked"))) でなければならない。 第一正規形が推奨される形である。

第二正規形では <annot-attributes> は要素ノードの必須要素である。 要素に属性や注釈がない場合には <annot-attributes>(@) としなければならない。 第二正規形では <comment><entity> は現れてはいけない。 解析済み実体は、外部実体であっても展開していなければならない。

第三正規形ではテキスト列はできるかぎり連結していなければならず、 <Nodelist> は連続したふたつのテキスト列ノードを含んではならない。

正規形にすることで SXML 要素に効率良くアクセスすることができるようになる。 SXML 文書が第三正規形であることがわかっている場合、 例えば、アプリケーションは <annot-attributes> の存在を確認しなくてもよい。 子ノードの存在確認やテキストデータの探索も同様に簡略化される。

簡単な例

     (some-name)        ; 属性のない空要素(第零正規形、および第一正規形)
     (some-name (@))    ; それを第二正規形にしたもの

以下に漸次複雑な例を示す。

XML SXML
     <WEIGHT unit="pound">
       <NET certified="certified">67</NET>
       <GROSS>95</GROSS>
     </WEIGHT>
     (WEIGHT (@ (unit "pound"))
       (NET (@ (certified)) 67)
       (GROSS 95)
     )
      <BR/>
     (BR)
      <BR></BR>
     (BR)
      <P>
     <![CDATA[<BR>\r\n
     <![CDATA[<BR>]]]]>&gt; </P>
     (*TOP*
       (P "<BR>\n<![CDATA[<BR>]]> "))

XML Namespaces 勧告にある例
     <!-- initially, the default
          namespace is 'books' -->
     <book xmlns='urn:loc.gov:books'
       xmlns:isbn='urn:ISBN:0-395-36341-6'>
       <title>Cheaper by the Dozen</title>
       <isbn:number>1568491379</isbn:number>
       <notes>
       <!-- make HTML the default namespace 
            for some commentary -->
          <p xmlns='urn:w3-org-ns:HTML'>
            This is a <i>funny</i> book!
          </p>
       </notes>
     </book>
     (*TOP*
       (urn:loc.gov:books:book
         (urn:loc.gov:books:title
             "Cheaper by the Dozen")
         (urn:ISBN:0-395-36341-6:number "1568491379")
         (urn:loc.gov:books:notes
           (urn:w3-org-ns:HTML:p
              "This is a "
               (urn:w3-org-ns:HTML:i "funny")
              " book!"))))

XML Namespaces 勧告にある別の例
     <RESERVATION 
       xmlns:HTML=
        'http://www.w3.org/TR/REC-html40'>
     <NAME HTML:CLASS="largeSansSerif">
         Layman, A</NAME>
     <SEAT CLASS='Y' 
       HTML:CLASS="largeMonotype">33B</SEAT>
     <HTML:A HREF='/cgi-bin/ResStatus'>
         Check Status</HTML:A>
     <DEPARTURE>1997-05-24T07:55:00+1
     </DEPARTURE></RESERVATION>
     (*TOP*
       (@ (*NAMESPACES* 
            (HTML "http://www.w3.org/TR/REC-html40")))
       (RESERVATION
         (NAME (@ (HTML:CLASS "largeSansSerif"))
           "Layman, A")
         (SEAT (@ (HTML:CLASS "largeMonotype")
                  (CLASS "Y"))
            "33B")
         (HTML:A (@ (HREF "/cgi-bin/ResStatus"))
            "Check Status")
         (DEPARTURE "1997-05-24T07:55:00+1")))

Acknowledgment

I am indebted to Kirill Lisovsky for numerous discussions and suggestions. He shares the credit for this page. The errors are all mine.

参考文献

[McCarthy] John McCarthy. Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I. Comm. ACM, 3(4):184-195, April 1960.
<http://www-formal.stanford.edu/jmc/recursive/recursive.html>

[Clark1999] Jim Clark. XML Namespaces. February 4, 1999.
<http://www.jclark.com/xml/xmlns.htm>

[Clark2001] James Clark, The Design of RELAX NG. December 6, 2001.
<http://www.thaiopensource.com/relaxng/design.html>

[Hughes1995] John Hughes, The Design of a Pretty-printing Library. Advanced Functional Programming, J. Jeuring and E. Meijer, Eds. Springer Verlag, LNCS 925, 1995, pp. 53-96.
<http://www.cs.chalmers.se/~rjmh/Papers/pretty.html>

[R5RS] R. Kelsey, W. Clinger, J. Rees (eds.), Revised5 Report on the Algorithmic Language Scheme. Higher-Order and Symbolic Computation, Vol. 11, No. 1, September, 1998 and ACM SIGPLAN Notices, Vol. 33, No. 9, October, 1998.
<http://www.schemers.org/Documents/Standards/R5RS/>

[SSAX] Oleg Kiselyov. Functional XML parsing framework: SAX/DOM and SXML parsers with support for XML Namespaces and validation. September 5, 2001.
<http://pobox.com/~oleg/ftp/Scheme/xml.html#XML-parser>

[SXML-short-paper] Oleg Kiselyov. XML and Scheme. An introduction to SXML and SXPath; illustration of SXPath expressiveness and comparison with XPath. September 17, 2000.
<http://pobox.com/~oleg/ftp/Scheme/SXML-short-paper.html>

[Parent-pointers] Oleg Kiselyov. On parent pointers in SXML trees. February 12, 2003.
<http://pobox.com/~oleg/ftp/Scheme/xml.html#parent-ptr>

[Lisovsky] Kirill Lisovsky. Case sensitivity of Scheme systems.
<http://pair.com/lisovsky/scheme/casesens/index.html>

[Lisovsky-NS] Kirill Lisovsky. Namespaces in XML and SXML.
<http://pair.com/lisovsky/xml/ns/>

[SXML-NS] Namespaces in SXML and (S)XPath. Discussion thread on the SSAX-SXML mailing list. May 28, 2002 and June 7, 2002.
<http://sourceforge.net/mailarchive/forum.php?thread_id=759249&forum_id=599>
<http://sourceforge.net/mailarchive/forum.php?thread_id=789156&forum_id=599>

[Annotations] An alternative syntax for aux-list. Discussion thread on the SSAX-SXML mailing list. January 5-14, 2004.
<http://article.gmane.org/gmane.lisp.scheme.ssax-sxml/37>

[DOM] World Wide Web Consortium. Document Object Model (DOM) Level 1 Specification. W3C Recommendation.
<http://www.w3.org/TR/REC-DOM-Level-1>

[XML] World Wide Web Consortium. Extensible Markup Language (XML) 1.0 (Second Edition). W3C Recommendation. October 6, 2000.
<http://www.w3.org/TR/REC-xml>

[XML Infoset] World Wide Web Consortium. XML Information Set. W3C Recommendation. 24 October 2001.
<http://www.w3.org/TR/xml-infoset>

[XML-Namespaces] World Wide Web Consortium. Namespaces in XML. W3C Recommendation. January 14, 1999.
<http://www.w3.org/TR/REC-xml-names/>

[XPath] World Wide Web Consortium. XML Path Language (XPath). Version 1.0. W3C Recommendation. November 16, 1999.
<http://www.w3.org/TR/xpath>

前の版からの変更点

Matthias Radestock の提案に従い <aux-list><annotations> に、 <aux-node><annotation> に変更した。 <attribute-list> と呼ばれていたものは <annot-attributes> になった。

Jim Bender から <PI> ノードの注釈に、例えば処理命令の文書内での位置を記録してはどうかという提案があった。

個々の属性や <TOP> への注釈についての詳細な議論を追加した。

<annot-attributes><annotation> の構文を精確に規定するために {a <B> <C> } というタグ付き集合の記法を導入した。

以前、SXML では属性リストと補助リストは以下のように定義されていた。

     [3]  <attributes-list> ::= ( @ <attribute>* )
     [15] <aux-list> ::= ( @@ <namespaces>? <aux-node>* )

このリストはどちらもタグ付き連想リストのようなかたちをしてい、 属性リストは @ でタグ付けされ、補助リストは @@ でタグ付けされる。 どちらも親要素のいわゆる子ではなく、どちらも省略可能である。 補助リストには「補助的な」関連付けが保存される。 例えば、もとの名前空間接頭辞の情報や親要素へのポインタなどである。 以下に属性リストと補助リストを持つ SXML 要素の例を示す。

     (tag (@ (attr "val")) (@@ (*parent* val)) kid1 kid2)

正規化された SXML(第二正規形)では、どちらもかならず存在し、 正しい順序で現れなければならない。 空の属性リストは (@) と表記され、 空の属性リストは (@@) と表記される。

現在の版では <attributes-list><annot-attributes> になり、<aux-list><annotations> になり、 <annot-attributes><annotations> もどちらも同一のシンボル @ でタグ付けされる。 正確に言えば、注釈は <annot-attributes> の内部かトップレベルにだけ現れる。先の例は現在では以下のようになる。

     (tag (@ (attr "val") (@ (*parent* val))) kid1 kid2)

あたらしい形式の注釈は不要な場合に読み飛ばすのが簡単になっている。 SXML アプリケーションが属性を名前で探索しているだけなら、 構文の変化は透過的である。 SXPath での注釈ノードの透過性が、<annot-attributes><annotations> に同じタグをつかった理由のひとつである。 これについては [Annotations] でより詳しく議論されている。 既存の SXML 処理コードのほとんどはこの変更の影響を受けないようである。 注釈を <annot-attributes> のなかに置くことで SXSLT 走査中に処理するのがより容易になると思う。 じっさい、これがこの変更のもともとの動機であった。

また、新形式では、ほとんどの要素に注釈も属性もないような文書について、 空間効率がよくなっている。 以前は注釈も属性もない SXML ノードは第三正規形で以下のように表されていた。

     (tag (@) (@@) data)

これが現在では (tag (@) data) のようになる。

より詳しい議論は [Annotations] を参照のこと。

以前は、第三正規形では注釈は省略できず、 ノードに注釈のない場合には、補助リストを (@@) で示さなければならなかった。 補助リストは要素ノードの 3 番目にかならず現れるので、 余計なテストをせずに子要素の位置をただしく特定することができた。 現在の版の SXML では <annotations><annot-attributes> に含まれる。 属性リストは順序のないものと見做され、大抵は assq をつかって処理される。 第三正規形で注釈の位置を規定したり省略不可とすることはもはや、 妥当とも、SXML の処理を目立って高速化するものとも思われない。 したがって、要素に注釈のない場合は <annotations> を省略することにした。 しかし注釈も属性もない場合は、第二正規形以上では依然として空の <annot-attributes> リストとして (@) を書かなければならない。