レベル: 初級 Brett D. McLaughlin, Sr. (brett@newInstance.com), Author and Editor, O'Reilly Media, Inc.
2007年 10月 09日 Brett McLaughlin が、文書構造から始まって、属性か要素か、という昔ながらの問題に至るまで、XML の基本のいくつかに立ち返ります。XML を最適化する方法を再び学び、いつも XML を最高の状態に保ちましょう。
私はこれまで、XML について、また XML 関連の話題について、無数の記事や本を書いてきました。そして少し時間をとってそれらを見直してみると、驚くべきことに気がつきました。私はプログラマーであり、いつもビットやバイトの世界に入り込むことを好み (私は大学でアセンブリー言語のコースを取り、それが大好きでした)、それらを完全に操ることが好きなのにも関わらず、私の記事やヒント、本の一般的な傾向としては、XML そのものを取り上げることが次第に減り、XML を操作する API や、そのような API をラップする API、そしてまったく XML に触れずに済む他の API を取り上げることが多くなっていたのです。
その結果、私達は実際に適切な XML を作成する方法を忘れてしまったのだろうか、という一般的な懸念が出てきました。さらに言うなら、私達は適切な XML とは何かを知っているのでしょうか。この短い記事では、XML の基本に関するいくつかのヒントを改めて見直します。その中で、私達はあらゆるツールを手にしていても、基本的な原則を忘れていないことを確認します。
最初のステップ: XML の適切な構成体を使う
現状で明確になった最大の問題の 1 つは、XML の作成者達 (ここでは、この言葉を広義に用いています) が、あらゆるものを要素の中に詰め込み始めた、という点です。属性や処理命令などは、過去のものとなってしまいました。
要素
XML 正しく作成する上で、要素の使い方を正しくすることはおそらく最も簡単なことでしょう。その大きな理由は、XML 作成者が何にでも要素を使う傾向があるからです。もちろん、そのような使い方は正しくなく、非常に深刻なマイナス面があります。XML での要素は、ほとんどの場合 (例外はありますが、ここでは最適な使い方について説明しています)、何らかの階層構造を持つデータ、あるいは少なくとも何らかの階層構造を持つ可能性のあるデータを表現するために使うのが最も適切です。最初に不適切なケースから示すことにすると、名前 (first name) が階層構造を持つことはありません。名前は 1 つの単語であり、それで終わりです。しかし、name 要素を持つことにするならば、それは適切な要素になる可能性があります。name は少なくとも名前と姓 (last name) に分けられ、場合によるとミドルネームや肩書き、その他のものにまで分解できるかもしれないからです。したがって、下記は要素の使い方としてあまり適切ではありません。
<firstName>Bob</firstName>
|
しかし下記は適切です。
<name firstName="Bob"
lastName="Zemeckis"
title="Mr." />
|
私がなぜ name 要素の中で firstName 要素と lastName 要素、そして title 要素をネストしなかったか不思議に思う人は、この直前の段落を再度読んでください。この点については、属性に焦点を当てる次のセクションで再度詳しく説明することにします。
一般的なルールとして、ある要素が文書の中の 1 つの場所に複数回現れることが考えられない場合には (例えば、家と職場という異なるタイプの 2 つの address 要素、あるいは 1 冊の本に対して 2 人の author 要素はあり得ます)、属性を使うように心がけることです。このルールが意味しているのは、要素を使う場合には必ずその要素が 2 度現れなければならないということではなく、単に 2 度現れてもかまわないということにすぎません。
要素がテキスト・データに最適である、ということも真実ではありません。適切な要素が属性しか持たず、テキストの内容をまったく持たない、というケースはたくさんあります (これについても、属性を取り上げる次のセクションを参照してください)。覚えておく必要がある最も重要なことは、XML には要素以外にも構成体があるということです。
属性
当然のことに思えるかもしれませんが、XML での属性は、1 つの値しか持たないデータに対して使う必要があります。例えば、ある人に対して要素を使う場合には、その人に関して値が 1 つしかないものを探してみると、見つかったものはおそらく属性になります。社会保障番号や ID、おそらく誕生日なども、どれも属性の候補として理想的です。
もちろん、属性のルールの例外は他のルールの例外よりも多いことがわかります。実際、属性が使われる頻度は、本来使われるべき頻度よりもずっと少ないと私は思います。開発者は、次のようにして要素を使ってスマートに見せたがる傾向があります。
<person>
<ssn>489098723</ssn>
</person>
|
しかし、これはまったく無意味です。社会保障番号は、まさに 1 つしか値を持たないデータです。もっと悪いことに、このように数字を要素にすることでパフォーマンスを無駄に低下させています。この例のように、ある要素の子を取得する場合には、要素ノードを取得し、その子ノードすべてをナビゲートし、それらの子ノードに対して繰り返しを行う必要があります。社会保障番号は最初のノードかもしれませんし、最後のノードかもしれず、明確ではありません。その後、そのノードの子 (この場合にはおそらく 1 つのテキスト・ノードから構成されています) を取得し、そしてそれらの値を取得する必要があります。したがって、このプロセスは次のようないくつかのステップを通ります。
- 親ノード (この場合は person 要素) を取得する。
- その子を取得する。
- 必要な子 (ssn 要素) が見つかるまで繰り返す。
- オプションとして、後の処理がしやすいように、この新しい要素のテキスト・ノードを正規化する。
- その要素の子を取得する。
- テキスト・ノードである子の値を取得する。
これを、属性を使って行う同じプロセスと比較してみましょう。
- 親ノード (person 要素) を取得する。
- その属性を取得する。
- 必要な属性 (ssn 属性) が見つかるまで繰り返す。
- その属性の値を取得する。
2 番目のプロセスでは、正規化の必要がなく (属性には必ずテキストが 1 つ関連付けられています)、子要素を処理する必要もありません。また私は、特定の子要素を取得するよりも要素の属性を取得する方が、ほとんどの場合高速であることにも気付きました。そのため、特に何千回もの繰り返しを行う場合には、パフォーマンスが大幅に向上します。
要するに、あまりスマートには見えなくても、私はむしろ下記のような XML を見たいと思っています。
<person ssn="489098723"
firstName="Bobby"
lastName="McKenza"
>
<occupation>
<occupation-type status="part-time"
job="author" />
<occupation-type status="part-time"
job="programmer" />
</occupation>
<address type="home"
street="112 E. Harney Way"
city="New York"
state="NY"
zip="10012" />
<!-- etc... -->
</person>
|
この XML は、ほとんどすべての情報が属性として記述されているため、たいていの人には奇妙なものに見えます。しかし私は、この方が属性の使い方としては適切だと考えており、10,000 回以上アクセスされる場合には、これによってパフォーマンスが目に見えて改善されると睨んでいます (これは実にわずかなパフォーマンスの改善でもアクセスの回数が多くなることで積み重なるためです)。
処理命令
私は処理命令 (PI: Processing Instruction) をあまり使いません。しかし、XML を使用する膨大な数の API が、今やコメントに特別なコードまたは命令を置くことを要求したり、あるいは名前空間やあらゆる特別な要素を使うこと、さらには内部に命令を持つ要素を使うことまで要求したりすることを煩わしく感じています。もし XML が処理 API またはツールに情報を提供する必要があるならば、それは処理命令であり、XML にはまさにそのための非常に明確な方法が備わっているのです。
皆さんは、特に XSL の領域で、次のようなものを見たことがあるはずです。
<?xml version="1.0"?>
<?xml-stylesheet href="classic.xsl" type="text/html"?>
<?xml-stylesheet href="alternate.xsl" type="text/xml" alternate="yes"?>
<article>
<!-- etc ... -->
</article>
|
この場合の PI は、この特定の XML 文書に対して XSLT プロセッサーがどのスタイルシートを適用する必要があるのかを XSLT プロセッサーに知らせています。この機能を無視するさまざまな API を詳しく学ぶよりも (ただし JAXB がすぐに頭に浮かびますが)、この機能を利用すればよいのです。この機能を利用した方が、次のようなコードよりもはるかによいのです。
<?xml version="1.0"?>
<!-- xml-stylesheet url="classic.xsl" document-type="text/html" -->
<!-- xml-stylesheet url="alternate.xsl" document-type="text/xml" -->
<article>
<!-- etc ... -->
</article>
|
私は、常日頃こうしたコードを目にしています。コメントには意味がありません。それに、コメントを利用して、その中の情報を命令として扱う API を使うのは非常に危険です。Javadoc や、文書を作成する API はコメントを使いますが、これらは少なくとも文書としてコメントを使っているのであり、実際に意味のある命令として使っているわけではありません。もちろん、こうした種類のマークアップを要求する API を選択した場合は仕方がありませんが、本来とは違う使い方で XML を使っているということを意識する必要があります。この点については、XML の仕様を作成した人達はきちんと認識しているはずです。
まとめ
もっと前に言っておくべきだったかもしれませんが、私は決して XML 純粋主義者ではありません。実際私は、XML には、思慮不足な部分や、見当違いな部分、あるいはまったく不適切な部分が数多くあると思っています。しかし、もし XML を使う選択をしたならば、XML を正しく使うためにはいくつかの基本的な考え方を守る必要があります。それをしないのであれば、そもそもなぜ、わざわざ XML を使う必要があるのでしょう。複数の値を持つ長いデータに対して要素を使わなかったり、ほとんど属性を使わなかったり、誤った使い方で PI を使ったり、あるいは PI を使わなかったりするのなら、そのデータを処理する独自言語またはパーサーをどこかの時点で作成した方が適切かもしれません。そうでないと、特定の目的用に調整された高速なパーサーの利点を享受できないまま、XML 特有の面倒な点 (冗長である点や、見た目が変な文書、エンコードの問題など) ばかりを抱えることになります。
ここで紹介した助言に関しては、XML を正しく使うため、あるいはセマンティクスの神々を喜ばせるためのものとは考えないでください。こうした考えに基づいて、皆さんの日々のプログラミング作業を行うのはよくありません。しかしこれらの助言を、XML をさらに活用するため、そしてよりパフォーマンスの良いソフトウェアを作成するための方法と考えれば、どれも大いに意味があるはずです。そうした考えに基づけば、ルールを破っても構いません。ただし本当に適切な理由が存在すればの話です。
参考文献 学ぶために
製品や技術を入手するために
議論するために
著者について  | 
|  | Brett McLaughlin氏は、Logo (小さな三角形を覚えていますか?) の時代からコンピューターの仕事をしています。現在の専門は、JavaおよびJava関連のテクノロジーを使ったアプリケーション・インフラストラクチャーの構築です。ここ数年は、Nextel Communications and Allegiance Telecom, Inc. でこれらのインフラストラクチャーの実装に携わっています。Brett氏は、Javaサーブレットを使ってWebアプリケーション開発のための再利用可能なコンポーネント・アーキテクチャーを構築するJava ApacheプロジェクトTurbineの共同設立者の1人です。同氏はまた、オープン・ソースのEJBアプリケーション・サーバーであるEJBossプロジェクトと、オープン・ソースのXML Web公開エンジンであるCocoonにも貢献しています。Brettの連絡先は、brett@oreilly.com です。 |
記事の評価
|