PowerShell ガイド:CLiXML

ひとことにXMLといってもeXtensibleMarkupLanguageなだけで、
自由度があるからもう少し制約を加えてみんなで認識した方がいいよねってこと。

ふつうのXMLでは「新宿で待ち合わせ」っていう記述や、「新宿駅で待ち合わせ」とか、
「新宿の東口出て200メートルまっすぐ進んだ地点で待ち合わせ」とか、わりとフリーなんですね。
あとでケータイで連絡とりあえばいいじゃん的な。

それを、住所にしてしまう。
時刻も確実に、目印の服装も決めておく。
たとえばそういうのがCLiXMLです。

そうすると、メールで一発解決。
必要な情報はすべて書いてある。
だから、情報の分解も組み立ても、ルールを知っていれば誰がやっても同じになる。
おやくそくの力です。

PowerShellでは、CLiXMLのファイルエクスポート/インポートをサポートしています。
オブジェクトを扱うものだから、これはとっても便利。
エクスポートしたXMLをとっておいて、あとでまたインポートできます。
やってみましょう。

#サンプル
$filename = "C:\test\tempfolder.xml";
$a = Get-ChildItem "C:\temp";
$a | Export-CliXml $filename;
$b = import-clixml $filename;
$a;
$b;

$aと$bを出力してみると、同じようにファイルとフォルダが並びます。
そりゃそうです、エクスポートしたのをインポートしたんですから。

だけどちがう点がある。

Compare-Object $a[0] $b[0];

比較してみると、どちらも同じファイルだったりするのに、相違するものとして結果が返ります。

Compare-Object ($a[0] | get-member) ($b[0] | get-member);

インポートしたものは、型からしてちがうんですね。
エクスポートする前は
System.IO.DirectoryInfo
だったのが、エクスポートしてインポートすると、
Deserialized.System.IO.DirectoryInfo
になっている。

Export-CliXmlはオブジェクトをシリアライズしてXML出力するわけです。
シリアライズで欠損するメンバがあるよということ。

...欠損なんて重要そうですが。欠けるのはメソッドです。
データとしてプロパティ構造が欠けるわけではなくて、
いまいきた生のインスタンスとしてのオブジェクトではないから、
インスタンスメソッドは使えないんですね。
そりゃそうです。
ファイルをつかめるかどうかわからない状況で、
Delete()なんてメソッドを提供しているのも考え物ですからね。
たとえば、1年前にエクスポートしておいたものを、
今日インポートしてファイルとかのオブジェクトについてメソッド実行できたら、ちょっとこわい。

デシリアライズで型をかえてインポート結果とsるのは、実は考慮の結果なのでした。

でも、じゃあ、Compare-Objectはどうするの?
そうですね、Compare-Objectはオブジェクトを比較するコマンドレットですが、
上記のように、いまとったのと昔とっておいたのを比較する場合、型ちがいで全部相違になります。
-両方ともいったんエクスポートしてインポートすればいいんじゃない?
-別の工夫をすればいいんじゃない?

正解はひとつじゃないです。考えてみてください。