VB.NETでもXMLを扱いたい(その4)

はじめに

無駄にダラダラ書いているこのシリーズですが、今回は『どうやって』ではなく『なぜ』XMLを扱うのか考えてみました。

弊社はとりあえず何に使うかは置いておいて何か気になることがあったらとりあえず突っ込んでおくスタンスです。 そうしておけばすぐには役に立たなくても、必要になった時にすぐに使うことができます。

とは言っても使うかどうかわからない技術を時間をかけて勉強するのは凄まじくコストパフォーマンスが悪いです。 弊社の愚行の例でいうと、自前の文字コードとかまず使いません。 嫌がらせぐらいにしか使えませんね。

というわけで、必要な時に必要なことが分かる即効性のあるテクニックの紹介サイトが重宝されるんじゃないかなと思います。 別にダメって訳じゃないですが、VBの場合は概念的な説明を行うサイトよりもコピペで使えるコードの紹介サイトの方が圧倒的に多いしそんなのでいいのかなーと疑問に感じています。

あれ、なんの話でしたっけ?

CSV、INI

話が全力で脱線しましたが、XMLと他の形式とで何が嬉しいのかを考えてみました。

比較して良いのか分かりませんが、まずはみんな大好きini形式とcsv形式との比較です。

INIファイル - Wikipedia

ini形式はいわゆるKey-Valueペアを保持する形式です。 この項目にはこの値を割り当てるという概念で、非ITエンジニアでも(編集させるのはどうかと思うが)比較的理解してもらいやすいです。 また、仕様が単純なので自前で実装する場合も簡単に実装できます。

ただ、大まかな仕様はある程度共通認識としてありますが、細かい実装はアプリケーションによって異なります。 なので、

なんでこのアプリケーションはダブルクォーテーションが使えないのよ(キィィィ

ってこともあるかもしれません。

csv形式はいわゆるスプレッドシートなどの表をテキストファイルで表現した形式です。 こちらも深く考えなければ(←これ大切)値をカンマで区切るだけのお手軽仕様で自前で簡単に実装できます。

一応RFC 4180で仕様化されていますがあくまでも『Informational』であり、アプリケーション独自の仕様が乱立しており『これに従っていればCSV』というものがありません。

対してXMLは階層型のデータ構造を表現します。木構造と表現しても良いかもしれません。 XML文書としての構文が決められており、csvのダブルクォーテーションとカンマの関係のようなアプリケーションによって微妙に解釈が異なると言ったことはありません。 また、XMLスキーマRELAX NG(リラクシング、今日調べてて初めて存在を知りました。)でかなり細かく構造を定義でき、また妥当性検証器で妥当かどうかの検証を行うことができます。

適切かどうかは置いておいてiniが保持できるKey-Valueペアやcsvが保持できる決められた項目がレコードとして連続する形式を保持することができます。 逆にinicsvではXMLが保持するデータを表すことはできません。

こう書くと

XMLすげー。すべての設定ファイルやEDIフォーマットをXMLに置き換えよう

となるかもしれません。

確かに開発リソースを割けるならすべてXMLにするのも悪くはないでしょう。 ただ、単純なKey-ValueペアをXMLで書いたり、限られた二者間で機械的にやり取りする(仕様が二者間で厳密に定義されている開放型ではないシステムで)csvでやり取りされていたデータをスキーマ付きXMLで置き換えるのは無意味と言ってもいいかもしれません。

出来ない訳ではないですが、メリットをほとんど享受できません。

<config>
  <property key="hoge1" value="fuga1" />
  <property key="hoge2" value="fuga2" />
  <property key="hoge3" value="fuga3" />
  <!-- 以下同様なものがつづく -->
</config>

対して、人間が関与する構造化されたデータ構造を定義する場合や、多数でやり取りするデータの場合はメリットを享受できるでしょう。 人間は馬鹿で愚かな存在ですから手で書いた設定ファイルにミスがあるかもしれません。 そのようなミスをあらかじめ定義した構造に沿って検出することができます。 また、多数でやり取りするデータについてもXMLスキーマを用いておかしなフォーマットのデータをあらかじめはじくことができます。

余談ですが、昔独自のフォーマットで定義されたiniの亜種のような設定ファイルを見たことがあります。 単純なiniの実装では表現できないデータ構造を表現しており、実装を見ると『そういう考え方もあるか』と妙に納得したのを覚えています。 ただし実装がかなり素朴で設定ファイル中のスペルミスをしてもエラーが出力されなく、間違いに気づかずに30分ほど悩んだのであれはちょっとなぁといった感じです。

JSONYAML

まぁ、普通XMLと比較するならこの二つだよねって感じの形式ですね。 ただし、大概は『XMLは冗長』の一言でマウントポジションをとられてボコボコにされるんですけどね。

ちょっと細かいことを言うとXMLはもともとマークアップ言語として設計されましたが、JSONYAMLはデータのシリアル化を目的として策定されたっぽいです。

なんと言ってもJSONYAMLXMLに対する利点は簡潔なことですね。 簡潔で分かりやすい。あぁ、なんて甘美な響きなのでしょう。

しかしながら弊社はあまりJSONYAMLについて詳しくない。 というか全くと言って良いほど知らないので、JSONYAMLXMLの比較はあまりできないです。

JSONYAMLスキーマ及びその処理系もあるのはあるみたいなのですが、XMLスキーマで妥当性検証を行っているようなものをJSONYAMLで置き換えるのは厳しそうです。 むしろ簡潔を旨としてスキーマレスで機械生成されたデータを運用するのが一般的なのでしょうか。

まぁ、わからんことをテキトーに書いてるとそのうちドアにIEDが仕掛けられそうなのでこの辺でやめます。

まとめ

XMLスキーマを用いれば妥当性の検証ができますが、それなりの手間が対価として必要になるのでiniやcsvといった旧来からあるフォーマットを簡単キレイに色あせない形で置き換えることは出来ません。

逆に妥当性の検証を行わなければならない用途ではXMLスキーマで構造を定義するだけで検証は妥当性検証器がやってくれますから妥当性の検証を行わなくてはならない場合においてはXMLスキーマ)はかなり有利です。

弊社は

iniやcsvは単純で古臭い形式だからクソ

XMLは冗長で複雑だからクソ

ということ主張したい訳ではありません。 それぞれの形式で利点・欠点があるのでそれぞれの目的に合わせて選択すればいいとおもいます。

むしろどちらかの形式にこだわって単純なKey-ValueペアをXMLで記述してコストだけ増大させたり、上の方で述べたXMLJSONYAML)で記述すべき階層を持つ形式を無理やりiniで記述することが間違いだと思ってます。

つまるところXMLはiniやcsvを完全に置換する銀の弾丸という訳ではなく、選択肢の一つとして考慮すべきものであるということです。 でもまぁ、csvはともかくiniの場合はキーはタグとして定義できそうなのでXMLで置き換えられそうですけど・・・。

冒頭の『なぜ』XMLを扱うかの答えは、

iniやcsvで表現できない複雑な構造を扱うことが出来、JSONYAMLと比べてスキーマを定義して妥当性の検証を行うのが(.NETで)楽であるから

というのが弊社の答えです。

まぁ、優劣があると言っても暗黒*1古代言語で扱う訳でなく.NETで扱うなら固定長フォーマットは勘弁願いたいですね。

COB・・・ウッアタマガ。よしよし悪い夢だったね〜。

*1:読みずらさ的な意味で、また不完全な構造化的な意味で、またGOTOが乱舞する様的な意味で