Windows Installer XML (WiX) を操作する PowerShell スクリプトを作成しています。これを行うために、.NET 3.5 の新しい XML API を使用しています。これは、DOM よりも操作が簡単な API であることがわかったからです。次のスクリプト フラグメントは、きっぱりと動作を拒否しています。
[System.Reflection.Assembly]::LoadWithPartialName("System.Xml.Linq") | Out-Null
# Basic idea: Iterate through en.wxl's l10ns, get string for each l10n, search all wxs files for that value.
pushd "C:\temp\installer_l10n"
$wxlFileName = "${pwd}\en.wxl"
$wxl = [System.Xml.Linq.XDocument]::Load($wxlFileName)
$strings = $wxl.Descendants("String")
$strings
$strings | foreach {
$_
}
popd
スクリプトは、各 <String> タグを別々の行に出力する必要があります。このバグが解決されたら、もっと面白いことをするようにします;-)
XML ドキュメントは、標準の WiX ローカリゼーション ファイルです。
<?xml version="1.0" encoding="utf-8" ?>
<WixLocalization Culture="en-US" xmlns="http://schemas.microsoft.com/wix/2006/localization">
<String Id="0">Advertising published resource</String>
<String Id="1">Allocating registry space</String>
...
</WixLocalization>
$strings は $null ではなく (明示的にテストしました)、$wxl を書き込みホストにすると、ドキュメントが読み込まれていることがわかります。$strings を Get-Member にパイプすると、「get-member にオブジェクトが指定されていません」というエラーが返され、write-host $strings は何もしません。$wxl.Descendants("WixLocalization") も試してみましたが、同じ結果が得られました。$wxl.Root や $wxl.Nodes などは期待どおりに機能します。PowerShell ISE でデバッグすると、予想される IEnumerable<XElement> ではなく、$strings が IEnumerator に設定されていることがわかります。IEnumerator を 1 つの MoveNext でテストし、次に Current でテストすると、"Current = "、おそらく $null であることが示されます。
奇妙なことに、以前のスクリプトでも同じ手法が機能していました。まったく同じコードですが、変数名と文字列リテラルが異なります。そして、そのスクリプトも(動作を確認するために)デバッグしようとしたところ、同じ動作を表示しているようです。