textdrop >
翻訳 >
ブログ >
Google C++ スタイルガイド 日本語訳,
Google Objective-C スタイルガイド 日本語訳,
コントリビュータのためのAndroidコードスタイルガイドライン 日本語訳,
Google XML文書フォーマット スタイルガイド 日本語訳
Google XML文書フォーマット スタイルガイド 日本語訳
はじめに
このドキュメントは、新しいXML文書フォーマットを設計するとき(また、既存のXML文書を拡張するとき(11章を参照))に使える一般的なガイドラインを提供する。文書フォーマットには通常、フォーマルな部分(DTDやスキーマ)と、普通の英語の文章で表現される部分がある。
ここに示すガイドラインは新しいXML文書を設計するときに適用するものであり、既に設計されたXML文書にまでさかのぼって強制するものではない。パブリックな、もしくはプライベートな文書フォーマットを設計するときに、このガイドラインを活用するのは望ましいが、このガイドラインを使ってグループの合意をコントロールしようとすべきではない。
このガイドラインは人手ではなく、マシンによって生成されマシンによって利用されるXMLを設計するために作られている。したがって、リッチテキストを表現するために作られたXHTMLやODFのようなフォーマットには、ここに挙げたルールを
適用することはできない(XHTMLにはできるだけHTMLと同様のフォーマットを使うべきだ)。XHTMLやその他のリッチテキストフォーマットではあるが、純粋にマシンで解釈可能な部分をコンテンツとして埋め込んだドキュメントもある。その場合、マシンで解釈可能な部分については、このスタイルガイドに従うべきだ。また、Protocol Buffer により変換されたものや、その他のフォーマット形式を介して処理されたXML文書フォーマットには、これらのルールの影響は及ばない。
このガイドラインの多くには、なぜそうしたのか、その理由が簡潔に述べられている。時代遅れにならないよう、同じようにメンテナンスしていく予定だが、これらはガイドラインとは見なされない。
なお本ガイドラインでは、MUST、MUST NOT、SHOULD、SHOULD NOT、MAYという言葉を
RFC 2119と同じ意味で使っている。
1. 設計すべきかせざるべきか、それが問題だ
- 既存のXMLフォーマットをできるだけ再利用しよう。それが拡張可能なフォーマットであればなおさらだ。完全に新規のフォーマットを作るのは、注意深く検討してからにすべきだ。まずはTim Brayの記事を読もう。そして、あなたのフォーマットを広くレビューしてもらおう。できれば、組織外部からもレビューしてもらおう。[理由: 新規の文書フォーマットというのはコストになる。ユーザはそれらをレビューし、文書化し、学習する必要があるためだ。]
- もし既存のフォーマットを再利用したり拡張しているなら、そこにある要素と属性を賢く利用しよう。それらが必須であればなおさらだ。
まったく別の目的を持たせてはいけないが、セマンティックスがそのまま当てはまらなくも、何とか工夫して使えないか考えてみよう。
そのフォーマットに必須の要素や属性があるのだが、自分のユースケースには適していない場合、最後の手段として、何らかの固定文字列を値として使おう。
[理由: 既存のマークアップを再利用するのはよいことだが、誤用してはいけない。]
- フォーマットを拡張するときには、既存のフォーマットにある暗黙のスタイルを使おう。それがたとえ、このガイドラインとは矛盾していてもだ。 [理由: 一貫性のため。]
2. スキーマ (Schemas)
- 文書フォーマットはスキーマ言語を使って表現すべきだ(SHOULD)。 [理由: 明瞭さとマシンによるチェック可能性のため。]
- スキーマ言語には、RELAX NG compact syntaxを使うべきだ(SHOULD)。微調整のために、組み込みスキマトロン (Schematron) ルールをスキーマに追加してもよい(MAY)。 [理由:
RELAX NGは最も柔軟性のあるスキーマ言語であり、設計上の制約というものがほとんどない。compact syntaxは非常に読みやすく学びやすく、必要に応じてXMLシンタックスへ一対一に変換することができる。スキマトロンを使うと、任意の要素間および属性間の制約をうまく扱うことができる。]
- スキーマには「Salami Slice(サラミスライス)」スタイル(要素ごとに1つのルール)を使うべきだ(SHOULD)。もし簡潔でシンプルなものであれば、「Russian Doll(ロシア人形)」スタイル (スキーマがドキュメントのようである)を使ってもよい(MAY) 。「Venetian Blind(ベネチア風日よけ)」スタイル(要素型ごとに1つのルール)はRELAX NGには適していないので、使うべきではない(SHOULD NOT)。
- 複雑な値の検証を助けるために、正規表現を提供すべきだ(SHOULD)。
- 既存の製品、ツール、ユーザとの互換性のため、DTDやW3C XML Schemaを提供してもよい(MAY) [理由: 私たちは一度に世界全体を変えることはできないため。]
3. 名前空間 (Namespaces)
- 要素名は名前空間内に入れなければならない(MUST)。ただし、名前空間を使っていない昔からある文書型を拡張する場合はその限りではない。
デフォルトの名前空間を使うべきだ(SHOULD)。 [理由: 名前空間のない文書は時代遅れだ。名前の集まりはすべて、どこかの名前空間に入れるべきだ。デフォルトの名前空間を使うと読みやすくなる。]
- 別の文書型から引用されたり、別の文書型で使われることを意図して作られた場合を除き、属性名を名前空間に入れるべきでない(SHOULD NOT)。 [理由: 名前空間に入っている属性名には常にプレフィックスを付けなければならない。これは入力するのが大変だし、読みにくい。]
- 名前空間名はHTTP URIである。名前空間名は http://example.com/whatever/year という形式にすべきだ(SHOULD)。ここで、whatever は文書型の名前に基づくユニークな値であり、yearは名前空間が作られた年になる。year の前に追加のURIパス部があってもよい。 [理由: 既存の規約のため。 年を提供すると、コード名を再利用することができる。]
- 特定の要素や属性のセマンティックスが互換性のない方法で劇的に変化する場合を除いて、名前空間を変更してはならない(MUST NOT)。 [理由: 名前空間を変更すると、クライアントのコードすべてに変更が必要になる。]
- 名前空間のプレフィックスは短くすべきだ(SHOULD)(しかし、別のプロジェクトと衝突するおそれがあるほど、短くすべきではない)。一文字のプレフィックスを使ってはいけない(MUST NOT)。プレフィックスは小文字のASCII文字だけを含むべきだ(SHOULD)。 [理由: 入力のしやすさと、エンコーディング互換性問題がないため。]
4. 名前と列挙値
注意: ここで言う「名前」とは、要素名、属性名、列挙値を指す。
- すべての名前は、lowerCamelCaseを使わなければならない(MUST)。つまり、小文字で始まり、以後、単語が出現するたびに大文字で始める。 [理由: ひとつのスタイルを採用することで一貫性が生まれる。こうすると、名前を参照するときに役立つ。キャピタリゼーションはよく知られており、改めて覚える必要がない。これはJavaのスタイルともマッチしており、それ以外の言語でも自動的に名前変換することでうまく扱える。]
- 名前はASCII文字と数字だけを含まなくてはならない(MUST)。
[理由: 入力のしやすさと、エンコーディング互換性問題がないため。]
- 名前は25文字を超えるべきではない(SHOULD NOT)。これよりも長い名前は、簡潔で意味のある名前になるよう工夫して、避けるべきだ(SHOULD)。ただし、名前をこの範囲に収めようとするとあいまいになるのであれば、この制限を無視すべきだ(SHOULD)。 [理由: 長い名前は使いにくく、余計な処理能力が必要になる。]
- 公開された標準的な略語は、十分に広く知られているものなら、名前の構成要素として使ってもよい(MAY)。その場限りの略語を使ってはいけない(MUST NOT)。camel-casingにおいて、頭字語は単語として扱わなければならない(MUST)。つまりinformationURIではなくinformationUriとする。 [理由: 特定のコミュニティにしか知られていない略語は、他の人がその文書フォーマットを使うときに理解できないことが多い(フルネームであれば理解できるのだが)。頭字語を単語として扱うと、単語境界がわかりやすくなる。]
5. 要素 (Elements)
- すべての要素は、空か、文字内容か、子要素のいずれかを含まなくてはならない(MUST)。混合内容(mixed content)を使ってはいけない(MUST NOT)。 [理由: たいていのXMLデータモデルは混合内容を適切に処理しておらず、要素の順序に依存している。例によって、テキストフォーマットはこのルールの範疇ではない。]
- 子要素の繰り返しをラップするだけのXML要素を使うべきではない(SHOULD NOT)。 [理由: これらはAtomで使われておらず、何も得られない。]
6. 属性 (Attributes)
- 文書フォーマットは開始タグにある属性の順序に依存してはいけない(MUST NOT)。 [理由: ほとんどのXMLパーサは順序を報告してくれない。また、XML Infosetの一部でもない。]
- 要素にたくさんの属性を持たせて、負荷をかけすぎるべきではない(SHOULD NOT)(経験則として10以下とする)。その代わりに、密に関連する属性をカプセル化するために子要素を使おう。 [理由: このアプローチをとると、XMLが要素に提供しているビルトイン拡張性を維持しながらも、仕様が発展したときに前方互換性を提供するのに役立つ。]
- 改行が重要になるような値を保持するのに、属性を使ってはいけない(MUST NOT)。 [理由: 仕様に準拠したXMLパーサは、こうした改行を空白に変換するため。]
- 文書フォーマットは属性値のまわりのシングルクォーテーションかダブルクォーテーションを許さなくてはならない(MUST)。 [理由: XMLパーサはその違いを報告してくれない。]
7. 値 (Values)
- 数値はすべて、10を基数とする、32ビット符号付き整数か、64ビット符号付き整数か、64ビットIEEE倍精度浮動小数のいずれかにすべきだ(SHOULD)。これらはそれぞれ、XML Schema型 xsd:int、xsd:long、xsd:doubleに対応する。もし特殊なケースで使う必要があるなら、xsd:integer(精度に制限のない整数)値を使ってもよい(MAY)。 [理由: XML Schemaにはあまりにも多くの数値型があるため。ここでは妥当なサブセットを提供している。]
-
ブール値は使うべきではない(SHOULD NOT)(代わりに列挙を使おう)。もしブール値が必要であれば、XML Schema型のサブセットであるxsd:booleanを使い、trueかfalseで表現しなければならない(MUST)。もうひとつのxsd:boolean値である1と0は使ってはいけない(MUST NOT)。 [理由: ブール値は拡張できないため。たとえこうしても、数値を許すという柔軟性がパーサからなくなることはない。]
- 日付はRFC 3339フォーマット、ISO 8601フォーマットとXML Schema型のxsd:dateTimeフォーマットのサブセットで表現すべきだ。ローカルタイムではなくUTCタイムを使うべきだ(SHOULD)。
[理由: あまりにも多くの日付フォーマットやタイムゾーンがあるため。たとえローカルタイムに重要な情報が含まれているとわかっていてもこうすべきだ。]
- 文字内容と属性値への埋め込み構文は使うべきではない(SHOULD NOT)。値に構文があるということは、主たる処理にXMLツールが使えないということだ。ただし、日付、URI、XPath表現といった構文は例外とする。 [理由: 特殊なパーサが必要になると、間違いが起こりやすい。ユーザはXMLパーサだけでXML文書を処理できるべきだ。]
- 値にある空白に注意しよう。XMLパーサは要素内の空白を取り除くが、属性内では改行を空白に変換する。アプリケーションフレームワークはさらに積極的に空白を取り除くかもしれない。あなたの文書フォーマットには空白を取り除くためのルールを入れておくべきだ(SHOULD)。
8. Key-valueペア
-
単純なkey-valueペアは、キーを名前にしてバリューをvalue属性とするような空要素として表現すべきだ(SHOULD)。value属性を持つ要素には、測定値の単位を示すために、unit属性を持たせてもよい(MAY)。物理的な測定単位には、SI systemを使うべきだ(SHOULD)。 [理由:
単純さと設計の一貫性のため。属性に値を置くとユーザから見えなくなる。キーを表示せずにバリューだけを表示しても役に立たないためだ。]
- もし取り得るキーの数が非常に大きかったり無限になるのであれば、key-valueペアを、key、valueおよび、オプションとしてunitやscheme属性を持つ単一の汎用の要素で表現してもよい(MAY)(ドメイン毎に区別して提供すること)。
その場合には、読めばわかる説明を入れたキーのリストも提供すること(必ずしも同一ドキュメントである必要はない)。
9. バイナリデータ
注意: バイナリデータをXML文書の一部に含めるべきか否かについて、厳格なルールはない。もしデータが大きすぎるなら、リンクにした方がよいだろう。
- XML文書にバイナリデータをそのまま直接入れてはいけない(MUST NOT)。Base64エンコーディングを使ってエンコードしなければならない(MUST) [理由: XMLは任意のバイナリデータを許していない。]
-
Base64によって必要とされる改行は省略してもよい(MAY) [理由: 改行は平文を簡潔にするために使われるが、XMLは実際のところ平文ではない。]
- Base64フォーマットが使われていることがわかるよう、xs:base64Binaryを値として指定したxsi:type属性を要素に付与してもよい(MAY)。 [理由: 不明確なデータの塊にはデコード命令を付与すべきだ。]
10. 処理命令 (Processing instructions)
- 純粋にローカルな処理の決まりごとを指定する場合を除いて、新たに処理命令を作ってはいけない(MUST NOT)。これは完全に避けるべきだ(SHOULD)。既に標準化されている処理命令は使ってもよい(MAY)。 [理由: 処理命令はXMLデータモデルに不自然に取り入れられており、常に要素で置き換え可能だ。これらは主に後方互換性を壊してしまうのを避けるためにある。]
11. XML文書インスタンスの表現
注意: プログラムが生成したインスタンスのフォーマットは、プログラマがコントロールできないことが多い(例えば、XMLシリアライゼーションライブラリが使われるため)。したがって、ここに挙げたポイントはガイドラインにすぎない。どんな場合であっても、XMLパーサがこのガイドラインに従っていることを当てにすべきではない。手作業でハックせずに、標準的なXMLパーサを使おう。
- 文字エンコーディングにはUTF-8を使うべきだ(SHOULD)。例外は極めてやむを得ない状況があるときだけにすべきだ。 [理由: UTF-8は世界中で広く使われているため。]
- 名前空間は可能な限り文書のルート要素で宣言すべきだ(SHOULD)。 [理由: 明瞭さと一貫性のため。]
- 名前空間URIのプレフィックスへの対応付けは、文書全体で一貫しているべきであり(SHOULD)、設計ドキュメントでも同じものを使うべきだ(SHOULD)。 [理由: 明確さと一貫性のため。]
- 標準的な名前空間には、(XHTMLのための)html:(Dublin Coreメタデータのための)dc:や(XML Schemaのための)xs:といった、よく知られたプレフィックスを使うべきだ。 [理由: 読みやすさのため。]
- タグ内には冗長な空白を使うべきではない(SHOULD NOT)。開始タグの各属性の前には、空白を1つ入れよう。もし開始タグが長すぎるなら、空白を改行に置き換えてもよい(MAY) [理由: 一貫性と簡潔さのため。]
- 空要素は空タグか、直後に終了タグが続く開始タグとして表現してもよい(MAY)。アプリケーションはこの2つのフォーマットを区別すべきではない。 [理由: XMLパーサはこれらを区別しないため。]
- 子要素にスペース2つのインデントを入れることで、きれいに印刷できるようにしてもよい(MAY)。文字内容を含む要素は折り返すべきではない(SHOULD NOT)。長い開始タグは最後を除く属性値の後ろに改行を入れて(おそらく余分なインデントを付けて)分割してもよい(MAY)。 [理由: 私たちが普段使っているスタイルと全体的に互換性をとるため。文字内容で折り返すと、その値に影響を及ぼすため。]
- 属性値はクォーテーションマークかアポストロフィで囲んでもよい(MAY)。
仕様ではこれらの利用を必須としたり禁止してはいけない(MUST NOT)。各種クォートをエスケープするのに、'や"を使ってもよい。 [理由: XMLパーサはこれらを区別しないため。]
- 実データを運ぶためにコメントを使ってはいけない(MUST NOT)。XMLに手書きでTODOを入れるのにコメントを使ってもよい(MAY)。外部に送信される文書にはコメントを入れるべきではない(SHOULD NOT)。 [理由: コメントはパーサによって捨てられることが多いため。]
- それでもコメントを使うのであれば、文書の先頭か子要素を含む要素だけにすべきだ(SHOULD)。もしコメントをきれいに印刷する必要があるなら、要素のように見えるが行を適切に折り返すこと。文字内容を含む要素にコメントを入れるべきではない(SHOULD NOT)。 [理由: コメント内や周囲に空白があると読みやすいが、文字内容にコメントを埋め込むと、空白の有無により混乱を招くおそれがある。]
- コメントを書くときには、<!--の後と-->の前に空白を入れるべきだ(SHOULD)。 [理由: 読みやすさのため。]
- CDATAセクションは使ってもよい(MAY)。これらは&や<を使うのと等価になる。仕様では、CDATAセクションの利用を必須としたり禁止してはいけない(MUST NOT)。 [理由: CDATAとテキストの区別や組み合せを報告するXMLパーサはほとんどなく、常に単一のオブジェクトとして報告するものが多いため。]
- &、<、>、"、'といったXML標準のエンティティ参照以外のエンティティ参照は使ってはいけない(MUST NOT)。文字参照は使ってもよいが(MAY)、文字エンコーディングがUTF-8のときには、実際の文字を使う方が望ましい。テキストフォーマットには通常、このルールは免除される。
12. 要素 対 属性
注意: いつ属性を使うべきで、いつ要素を使うべきかを決めるための厳格なルールはない。以下には、設計者が考慮すべき検討項目をいくつか挙げる。理由の項目はない。
12.1. 一般論
-
要素と比べて属性には制限がある。そして、どんな設計にも必ず要素が含まれる。したがって、すべてを要素として設計するのが最も単純だ。ただし、これがベストだとは限らない。
-
木構造のデータモデルの場合、通常、要素は内部的にノードとして表現される。属性を表現するのに使う文字列と比べると、ノードの方がメモリをたくさん使用する。ノードはアプリケーション固有のクラスになることがある。そして、多くの言語では、こうしたクラスを表現するのにメモリが必要になる。
-
ストリームの場合、要素は一度に1つ処理される(おそらく1つずつだが、これはあなたが使っているXMLパーサに依存する)。それに対して、要素の属性およびその値は、すべて一度に報告される。これはメモリに負担をかけることになる。属性値が非常に長いと、なおさらだ。
-
要素内容と属性値はいずれも、適切にエスケープする必要がある。したがって、エスケープを設計の判断材料とすべきではない。
-
プログラミング言語やライブラリによっては、要素を処理する方が簡単なものもあれば、属性を処理する方が簡単なものもある。処理の簡単さを判断基準に使うのには注意しよう。具体的に言うと、XSLTはどちらも同等の簡単さで処理できる。
-
もしそのデータがユーザに見せるべきものなら、要素を使うことを検討しよう。見せるべきものでなければ、属性を使うことを検討しよう。(このルールはなぜか破られることが多い。)
-
もし既存のスキーマを拡張しているなら、そのスキーマでやられているのと同じようにしよう。
-
賢いスキーマ言語(ここではRELAX NGとスキマトロンを意味している)では、要素と属性を対称的に扱っている。DTDとXML Schemaのような古くて未熟な スキーマ言語では、要素のサポートの方が手厚い傾向がある。
12.2 要素の利用
-
データモデルにおいて、データが1回以上出現する可能性があるなら、foo1, foo2, foo3 ...といった名前の属性を使うのではなく、要素を使うこと。
-
独立したオブジェクトとして見なせる情報を表現しており、その情報に別の情報との親子関係があるときには、要素を使うこと。
-
厳密な型付けや関係ルールをデータに組み込むときには、要素を使うこと。
-
もし2つのデータに順序関係があるなら、要素を使うこと。属性には本質的に順序がない。
-
もしデータにそれ自体のサブ構造がある、もしくはその可能性があるなら、要素を使うこと。サブ構造を属性にしてしまうと、必ず面倒なことになる。同様に、データが大きなデータの構成要素になるのであれば、それを要素として入れるようにしよう。
-
先ほどのルールには例外がある。空白で分離された複数のトークンは、属性として安全に入れることができる。セパレータは具体的に何でもよいのだが、スキーマ言語のバリデータは現在のところ、空白しか扱えない。したがって、空白にするのがベストだ。
-
もしデータが複数行にわたるなら、要素を使おう。XMLパーサは属性値にある改行を空白に変えてしまうためだ。
- もしデータが非常に巨大であれば、要素を使おう。そうすれば、その内容をストリームとして扱うことができる。
-
もしデータが自然言語であれば、要素に入れよう。そうすれば、使われている言語を示すのにxml:lang属性を利用することができる。日本語のような自然言語の場合、慣例として、子要素によるアノテーションを使うことがある。ヘブライ語やアラビア語のような右から左に書く言語も同様に、双方向性(bidirectionality) をうまく管理するための子要素が必要になる。
12.3 属性の利用
-
もしデータが、カタログやコードのリストなど、管理されている語彙に由来しているなら、できるだけ属性に入れよう。例えば、言語タグ、通貨コード、医療診断コードなどは、属性として扱うのがベストだ。
-
もしデータが実際には別のデータのメタデータであれば(例えば、主たるデータが提供するクラスや役割を表現していたり、その処理方法を指定しているような場合)、できるだけ属性に入れよう。
-
具体的に言うと、もしデータが別のデータのID自体であったり、IDへの参照であれば、その識別子に相当するものを属性に入れよう。もしそれがIDであれば、xml:idという属性名を使おう。
-
ハイパーテキストの参照は、慣例としてhref属性を使うこと。
-
上書きしない限り、データがその要素およびその任意の子孫要素に適用されるなら、属性に入れるのが通例だ。よく知られた例として、xml:lang、xml:space、xml:base、名前空間宣言がある。
-
もし簡潔であることが本当に最重要であれば、属性を使おう。しかしながら、代わりにgzip圧縮が使えないか検討しよう。これは反復構造の多い文書では、非常にうまく機能する。
13. 終わりに
常識を働かせよう、そして、一貫性を持たせよう。拡張性を持つよう設計しよう。いつか必要になるはずだ。 [理由: 長く辛い経験から。]
XMLフォーマットを設計するときには、数分かけて他のフォーマットを調べて、スタイルを決めよう。スタイルガイドラインがあるおかげで、どうやって話すかではなく、何を話すかに集中できるようになる。
もし、こうしたルールに奴隷のように従うことによって、未熟で無原則で実に嫌らしい設計上の混乱をきたすようであれば、これらのルールのいずれか、あるいは、すべてを破ってしまおう。(たとえ、それがMUSTであってもだ)。具体的に言うと、「単純なもの」と「複雑なもの」、「メタデータ」と「データ」のように、はっきり異なる2つのグループに分類できるとき、両方を使うのが理にかなっていることは多いが、属性と子要素がランダムに組み合わさると、従うのも使うのも困難になる。
新米は必ずこう尋ねる。
「要素か、それとも、属性か、
どちらにすべきでしょう?」
知ったかぶりは獅子のように吠え、
賢いハッカーは虎のように微笑む。
-- 短歌(tanka)、もしくは長い俳句(extended haiku)
[TODO: スキーマレジストリが用意できたら、そこへのリンクを追加する]