SXML

出典: フリー百科事典『ウィキペディア(Wikipedia)』
Jump to navigation Jump to search
SXML
拡張子 .sxml, .scm
MIMEタイプ text/sxml
タイプコード TEXT
種別 マークアップ言語

SXMLは、XMLデータをS式の形式で記述、処理するための方法である。

SXMLとXMLの字句上の対応について、小さなサンプルのXMLを以下に示す:

XML SXML
<tag attr1="value1"
     attr2="value2">
  <nested>Text node</nested>
  <empty/>
</tag>
(tag (@ (attr1 "value1")
        (attr2 "value2"))
  (nested "Text node")
  (empty))

上記の例から、以下の2つの点に気づくであろう:

  1. XMLとSXMLの字句上の表記はよく似ている: 非形式的に言うと、SXMLは山括弧の代わりに丸括弧を用いているという点でXMLとは字句的に違う。
  2. SXMLは、XMLデータに対する直接的な字句上の表記というだけでなく、既存の数多くのプログラミング言語で第一級またはそれに準ずる基本的なデータ構造でもあり、それゆえ汎用のプログラミング言語によるXMLデータ処理の実例になっている。

SXMLとして具現化されたS式がXMLと似ていることから、XMLデータとプログラミング言語を密接に統合でき、結果としてアプリケーションにおけるXMLデータの処理が説明的で単純になる。

開発動機[編集]

XMLのデータ処理言語は、例えばXPathXSLTXQueryが、W3 Consortiumにより提案されている。しかし、これらは、汎用的なプログラミング言語ではなく、アプリケーションの全てを実装するには不十分である[要出典]。 この理由により、ほとんどのXMLアプリケーションは、CJavaのような伝統的なプログラミング言語、もしくはPerlJavaScriptPythonのようなスクリプト言語を用いて実装される。

2つの異なる言語(例えば、XPahtとJava)を組み合わせる試みは、インピーダンス・ミスマッチとして知られる問題を引き起こす。 インピーダンス・ミスマッチは、2つの側面からなる:

インピーダンス・ミスマッチは、複雑なコンバータと、2つの言語を結びつけるのに使用するAPI(例えば、DOM)を要求する。

インピーダンス・ミスマッチの問題を軽減もしくは消し去るために、Scheme関数プログラミング言語をXMLのデータ処理に使用する[1]事ができる:

  • ネストしたリスト(SchemeにおけるS式)は、ネストしたXML文書の自然な表現を提供する。Schemeは、コードとデータを、動的な型の要素のネストしたリストで表現し、XML文書(ネストしたXML要素の階層構造からなる)は、階層的なネストしたSchemeのリスト(所謂、S式)と考えることができる。
  • Schemeは、ほとんどのXML用の言語(例えば、XSLTとXQuery)と同じく関数型言語である。Schemeは、(ネストした)リストを再帰的な方法で処理する。この方法は、文書ツリーを、渡り歩く/変換する処理と考えることもできる

Scheme(LISPの方言である)は、広い意味でのスクリプト言語である。Schemeは、実際に使用されている、最も洗練され、コンパクトなプログラミング言語の一つである: Schemeの標準の記述は、わずか40ページである。 Schemeは、高水準言語であり、高速なプロトタイピングに向いている。 さらに、Schemeプログラムは、一般的に、同じ機能のCプログラムよりも何倍もコンパクトである。

XMLとSXMLの字面は、とても似ている: 非公式には、SXMLは、XMLの開始/終了 タグを開き/閉じ 括弧で置き換える。 一方、SXMLは、S式であり、それゆえ、Schemeプログラミング言語の主なデータ構造であり、結果として、Schemeを経由して、簡単かつ自然に処理できる。

XML, XMLインフォメーション・セットとSXML[編集]

XML文書は、本質的に、ツリー構造である。 ルート要素英語版の開始と終了タグは、文書の全ての内容を囲っていて、各内容は他の要素や任意の文字データを含む。 角ブラケットの文字列は、XML文書の外部表現である。 アプリケーションは、内部の形式で扱う: XML Information Set、もしくは、特別なものとして(例えば、DOM)として扱うべきである。 この内部形式を持ちいると、アプリケーションは、特別なデータ、もしくは、XMLツリーを別のツリーに変換したデータと位置づける事になる。

W3 Consortiumは、XMLインフォメーション・セット(インフォセット)を抽象データセットとして定義した。インフォセットは、整形式XML文書で利用可能な情報を記述する。

XML文書のインフォメーション・セットは、多くの「情報項目 (information item)」から構成され、情報項目が表すのは、要素、属性、文字情報、処理命令、と、その他の文書の項目である。 各情報項目は、多くの関連付けられた属性を持つ。例えば、名前、名前空間URIである。 いくつかの属性 -- 例えば、子要素と属性 -- は、他の情報項目のコレクション英語版である。 しかし、技術的には、インフォセットはXMLに特化したものであり、他の半構造化データ英語版の書式、特にHTMLに大部分が適用される。

XML文書の構文解析は、XMLインフォセットのインスタンスを生成する一つの方法でしかない。

注意すべき事に、XMLインフォメーション・セットの勧告は、包括的なものをもたらすのではなく、最低限の情報と属性のセットを構築することである。 勧告の目的は、一貫性のある定義のセットを提供し、整形式のXML文書の中の情報を参照するのに必要な他の仕様でも使えるようにすることである。

XMLインフォメーション・セット勧告で定義される抽象データモデルは、W3コンソーシアムの全てのXML関連の仕様に適用可能である。 すなわち、ドキュメント・オブジェクト・モデルは、情報項目を扱うためのAPIと解釈できる; XPath data model英語版は、情報項目から派生するノードの概念を利用している、等。 DOMとXPathデータモデルは、それゆえ、2つのXMLインフォメーション・セットのインスタンスである。

XMLインフォメーション・セット勧告は、それ自体ではデータ構造や、情報項目へのアクセスのインタフェース (情報技術)に制限を設けていない。 それゆえ、XMLインフォメーション・セットから抽象データモデルへの別の変換方法が可能である。 例えば、XMLインフォメーション・セットを、ツリー構造と解釈し、"インフォメーション・セット"と"情報項目"は、それぞれ一般的な用語である、"ツリー" と "ノード英語版"と同じであると解釈するのは、役に立つ。

情報項目は、項目自身の属性のコンテナと解釈でき、そして、テキストの文字列(例えば、名前、名前空間URI)や、項目自身(例えば、XMLの子要素)も同様であるかもしれない。

インフォメーション・セットは、それゆえ、ネストしたコンテナの階層である。 このようなコンテナの階層、つまりテキストの文字列と他のコンテナから構成されるコンテナの階層は、一般的にS式によって記述できる。なぜなら、S式は、リストのメンバーはアトムの値かS式自身であると、再帰的に定義されるからである。 S式は、簡単に、トラバースに適した内部表現にパースできる; S式には、簡潔な外部表記法があり、S式は、比較的容易に、手作業ででも、構築する事ができる。

SXMLは、XMLインフォセットの、S式による完全なインスタンスである。 インフォセットのゴールは、全ての関連するデータの書式と、データの抽象化、データ同士の関連のコンテナ・スロットを提示することである。 SXMLは、S式で完全に具象化した、ネストしたコンテナを与え、情報項目と属性へのアクセス手段を供給する。 SXMLは、XPathDOM(これらは、XMLインフォセットの2つの別のデータモデルでもある)の親戚である。 SXMLは、とりわけSchemeベースの XML/HTMLの記述、XPathクエリ、ツリーの変換に向いている。

XMLとSXMLは、それゆえに、XMLインフォメーション・セットについての、2つの文法的に異なった表現と考える事ができる。

SXML仕様[編集]

前節で指摘したように、SXMLは、XMLインフォセットをS式の書式で完全にインスタンス化したものである。 本節でのSXMLについてのさらなる議論は、SXML仕様に基づくものである。

簡潔なSXMLの文法をEBNF記法にて以下に示す。 SXMLの<name>は、単一のSchemeシンボルである。

[1]              <TOP> ::= ( *TOP* <PI>* <Element> )
[2]          <Element> ::= ( <name> <attributes-list>? <child-of-element>* )
[3]  <attributes-list> ::= ( @ <attribute>* )
[4]        <attribute> ::= ( <name> "value"? )
[5] <child-of-element> ::= <Element> | "character data" | <PI>
[6]               <PI> ::= ( *PI* pi-target "processing instruction content string" )

XMLインフォセットの一つの情報項目は、属性の集まりであるから、リストは、とりわけ項目を表現するのに好都合なデータ構造である。 リストの最初、Schemeの識別子は、情報項目の名前である。 多くの情報項目にとって、この識別子が、(拡張された)項目名である。 XML要素と表記される情報項目には、要素名で始まるリストが対応し、オプションとして属性のコレクションが続くことがある。 要素の項目のリストの残りは、要素の子要素、文字データ、処理命令、とその他の要素が順番に並んだものである。 全ての子要素は、一意である; 項目は決して、子要素を共有しない。たとえ、子要素が独自の内容を含んでいたとしてもである。

次の例は、XML要素とそれに対応するSXML記法での表現を説明したものである(<Element>の表記をSXMLの文法でおこなった)。

<WEIGHT unit="pound">
  <NET
   certified="certified">67</NET>
  <GROSS>95</GROSS>
</WEIGHT>
(WEIGHT (@ (unit "pound"))
  (NET
   (@ (certified)) "67")
  (GROSS "95"))

属性の値は、通常は文字列である; 属性は(HTMLにおいて)、ブーリアン型の場合は省略される事がある。例えば、上記の例では、"certified"属性の場合である。

属性の集まりは、情報項目の右の@の特別な名前でタグ付けされたものと解釈される。"@"の文字は、整形式XML文書の名前には現れない; それゆえ、<attributes-list>が要素を表すリストと取り違えられる事はない。 XML文書は、属性や、処理命令と他のメタデータで、要素がマークアップされる。

対象的に、SXMLは、要素とメタデータが統一的に、タグ付きリストで表現される。 RELAX NG -- XMLのためのスキーマ言語 -- も、属性を要素と共に統一的に扱う事を目的としている。 この統一的な処理は、ジェームズ・クラークによれば、言語の単純化についての、ある種の兆候である。 SXMLの有利な点は、全てのXMLの名前は有効なSchemeの識別子であるが、全てのSchemeの識別子が有効なXMLの名前ではないという点である。 この事実によって、@, *PI*, *TOP*のような管理用の名前を、XMLの名前との衝突の心配なしに導入できる。 さらに、XMLとSXMLの関係をWell-definedなものとする。 SXMLに変換されたXML文書は、(インフォセットの範囲内で)等価なXML文書に再構築する事ができる。 さらに、インフォセット仕様で与えられた実装の裁量範囲において、SXML自身は、インフォセットのインスタンスである。

XMLの推奨は、処理命令 (PI) は、要素や文字データと区別できる事を指示している; 処理命令は、アプリケーションを通さなければならない。 SXMLにおいては、それゆえ、PIは専用の型である*PI*のノードで表現される。 XPathDOM Level 2も、同様の方法で処理命令を扱っている。

XML文書と、それに対応するSXML表現のサンプルの両方を以下に示す。これらは、ネストしたXMLのタグとネストしたSXMLのリストの比較例を提示している。

SXML文書の方が、同等のXMLよりも僅かにコンパクトである事に注意してほしい。

<?xml version='1.0'>
<di contract="728g">
  <wt refnum="345">
    <delivery>
       <date month="6" 
             day="01" 
             year="2001"/>
       <weight>783</weight>
    </delivery>
    <vehicle type="lorry" 
             number="A567TP99"/>
  </wt>
  <wt refnum="459">
     <vehicle type="car" 
              number="25676043"/>
  </wt>
</di>
(*TOP* (*PI* xml "version='1.0'") 
(di (@ (contract "728g"))
  (wt (@ (refnum "345")) 
    (delivery
      (date (@ (month "6") 
               (day "1") 
               (year "2001")))
      (weight "783"))

    (vehicle (@ (type "lorry") 
                (number "A567TP99"))))

  (wt (@ (refnum "459")) 
    (vehicle (@ (type "car")
                (number "25676043"))))))

SXMLは、XML文書をパースした、抽象構文木であると考える事もできる。 XML文書もしくは、整書式になっているXMLの一部分は、自動的に、対応するSXML形式に、SchemeのXMLパース・フレームワークのSSAXを用いて変換される。

注目に値するのは、SXMLは、XML文書に含まれる全ての情報を表現する事である。コメント、XML名前空間や外部エンティティも含めて。 これらの事は、単純にするために本節では省かれているが、SXMLの仕様では検討されている事である。

[編集]

例えば、簡易なXHTMLページは、以下のようなものがある:

 <html xmlns="http://www.w3.org/1999/xhtml"
         xml:lang="en" lang="en">
    <head>
       <title>An example page</title>
    </head>
    <body>
       <h1 id="greeting">Hi, there!</h1>
       <p>This is just an &gt;&gt;example&lt;&lt; to show XHTML &amp; SXML.</p>
    </body>
 </html>
 

これをSXMLに変換すると以下のようになる:

 (*TOP* (@ (*NAMESPACES* (x "http://www.w3.org/1999/xhtml")))
  (x:html (@ (xml:lang "en") (lang "en"))
    (x:head
       (x:title "An example page"))
    (x:body
       (x:h1 (@ (id "greeting")) "Hi, there")
       (x:p  "This is just an >>example<< to show XHTML & SXML."))))
 

各要素のタグのペアは、括弧のセットに置き換えられる。タグの名前が終わりの部分で繰り返される事はなく、単にリストの最初のシンボルになるだけである。要素の内容が要素名に続き、内容は要素自身か、文字列である。XMLの属性については特別な文法はない。SXMLにおいては、属性は単純に別のノード、特別に@の名前を持つノードで、表現される。これが、実際の"@"タグと衝突する事はない。なぜなら、@は、XMLではタグの名前として許されていないからである。これは、SXMLで共通のパターンである: いつでも、タグが特別な状態や物事を示すのに使われ、そのタグはXMLでは使われる事はなく、その名前を使って有効なXMLの識別子を作る事はできない。

また他に、"escape"や他の特別な意味を持つ文字、& and > as &amp; and &gt; エンティティのような文字が必要ない事を見てとれる。全ての文字列の内容は、自動的にエスケープされる。何故なら、それらは純粋に内容と解釈でき、タグやエンティティを中に含まないからである。これはまた、自動的に生成された内容を中に挿入するがずっと容易であり、エスケープし忘れる危険を侵さずに、生成内容を別のユーザーに表示できる。(これらは、全ての種類のやっかいなクロスサイト・スクリプト攻撃や、他の頭痛の種を引き起こす)

SXMLの特徴[編集]

本節では、SXMLの文法とS式の性質から差し引かれる、SXMLのいくつかの重要な特徴について考察する。

SXMLの属性[編集]

SXMLの属性リストのcdr英語版連想リストであり、それゆえ、SXMLが、LISPのプログラミングによって読み込まれる時、全てのSXMLの属性は、属性リストから、Lispのビルトインのassoc機能を用いて、変換する事ができる。

SXMLの要素と属性[編集]

SXMLの統一的な、要素、属性、処理命令の表現は、クエリや変換をシンプルにする。 SXMLのデータモデルでは、属性や処理命令は、通常の要素から名前を消し去ったものように見える。 そのため、属性専用のクエリや変換関数は、冗長なものになる。何故なら、要素の名前を消した形の通常の関数が使えるからである。

このSXMLの要素と属性の統一的な表現は、特に実務において役立つ。 XMLの要素と属性の間の違いは、ぼやけてくる。 要素か属性のどちらを、現実の現場の情報の表現に使用するかは、しばしば流儀の問題であり、後で変更できる選択である。 データ構造内のこのような変更は、SXMLにおいては、単にひとつの階層のレベル(属性リスト)での追加/削除で表現できる。 この事は、SXMLのアプリケーションは最小の修正済む事を意味する。 SXMLの記述にとっては、属性と要素のわずかな違いは、構成内容が、属性リスト(特別なSXMLのノードである)に含まれている事と、ネストした要素を持てない事である。

例えば、もし、配達 (delivery) の重さ (weight) についてのデータの再構成が必要になり、最初はネストした要素だったものを属性で表現すると、SXMLの要素は、以下のようになる。

(delivery
   ...
   (weight "789")))

will be changed to

(delivery
  (@ (weight "789"))
  ...)

このような、要素と属性の記述方法は、SXMLデータの再構成を単純にし、データ処理に用いられるクエリを統一的なものにする。

統一的なノードのツリーとしてのSXML文書[編集]

SXML文書は、本質的にツリー構造であるので、このツリーのノードに対して、SXML ノードの用語を導入する事により統一的な方法で表現できる。

SXMLのノードは、以下の単一の生成規則[N]のSXML文法で定義できる。 また、代わりに、SXMLノードは、2つの相互再帰的なデータ型を含むセット: [N1], [N2] と [N3]、として定義する事も可能である。 後者の場合、ノードは、自身の一番左のメンバーとして、ノードリストに対する名前を加える事によって構築される; ノードリスト自体は、ノードの(ソートされた)リストである。

[N]      <Node> ::= <Element> | <attributes-list> | <attribute> | "character data: text string" | <TOP> | <PI>
[N1]     <Node> ::= ( <name1> . <Nodelist> ) | "text string"
[N2] <Nodelist> ::= ( <Node> <Node>* )
[N3]    <name1> ::= <name> | @ | *TOP* | *PI*

このような解釈は、SXMLのツリー構造と、S式による、情報項目の統一的な表現を強調する。

SchemeプログラムとしてのSXML[編集]

LISP系列のプログラミング言語の文法、特にSchemeは、データとコードの両方の表現に使われるS式に基づく。この事は、Schemeのプログラムが半構造化データとして扱われたり、その逆を可能かつ簡便にする。

SXML文書とそのノードはS式なので、これらをSchemeのプログラムの表現に使用できる。この事を可能にするのに十分条件は、SXMLツリー内のリストの最初のメンバーが関数であることである; マクロを使用すれば、より多くの事が可能になる。そして、リスト残りのメンバーは引数になり、引数は関数に引き渡される。SXMLの文法によれば、属性と要素名と特別な名前は関数に関連付けられなければならない。

これらの条件を満たす、SXML文書もしくはSXMLノードは、評価可能なSchemeプログラムとみなせる。例えば、eval関数を用いて評価できる。

例として、もし、paraboldが以下の様に関数として定義されているとする:

(define (para . x) (cons 'p x))
(define (bold . x) (cons 'b x))

この場合、次のSXML要素は

(para "plain"
      (bold "highlighted")
      "plain")

プログラムとして扱う事ができ、その評価の結果はSXML要素である:

(p "plain"
   (b "highlighted")
   "plain")

プログラムの評価の結果は、必ずしもSXMLの要素である必要はないことに注意すること。 主に、プログラムは、XMLもしくはHTML形式のソースのデータの表現を返す; もしくは、副作用、例えばSXMLデータを関係データベースに保存するかもしれない。

SXMLの短所[編集]

リストの表現の根本は、片方向リストであるため、ノードは、自身の前にある兄弟や親のノードへのアクセス方法がない。ほぼすべての、DOMとXPathのトラバース操作は、SXMLでも行き詰まる事なく可能であるが、親ノードからの各々のノードの位置や、トラバースした子ノードのインデックや、現在のノードのパスは操作できない。

DOMの「NodeList.item」もしくは、XPathの「[] 」アクセサのような任意の位置のクエリには、向いていない。なぜなら、リストは、n版名のノードまでたどらなければならなく、この処理はO(n)の計算時間がかかる。それに対して、ベクトルや配列のアクセスはO(1)ですむ。

実際、SXMLと、それに似たS式をXMLの表現するために用いたフォーマットは、シーケンシャル処理の向いている。例えば、SAXのイベント処理や、XMLへ属性の追加やシリアライズのようなものに向いている。可能な変換処理は限られており、前の兄弟や親のノードを必要としないものや、単純さを放棄して、スタック構造を使用しない変換処理のみである。

出典[編集]

  1. ^ Kirill Lisovskiy, Dmitry Lizorkin. "SXML: an XML document as an S-expression" // Russian Digital Libraries Journal. – Moscow: IIS, 2003. – Vol. 6, No 2. – ISSN 1562-5419. - http://modis.ispras.ru/Lizorkin/Publications/sxml-eng.pdf

外部リンク[編集]

Detailed introduction, motivation and real-life case-studies of SSAX, SXML, SXPath and SXSLT. The paper and the complementary talk presented at the International Lisp Conference 2002.