PowerShell で xpath 使って [cs|vb]proj ファイル読み書きしたい時

  • 5
    いいね
  • 0
    コメント

昔の C# や VB.NET のプロジェクトが沢山あり、最新の .NET Framework にマイグレーションしたい時、プロジェクトファイルの PropertyGroup や ItemGroup の設定値を更新する移行用のスクリプト書きたくなりますよね。

で、こんな感じで普通に xpath を指定して要素を取得しようとしてもちゃんと取れません。

$proj = [xml]Get-Content Target.csproj

$nodes = $proj.SelectNodes("//ItemGroup/Reference[contains(./@Include , 'System')]")

foreach($node in $nodes) { Write-Host $node.Include }

xpath に MSBuild のスキーマ情報を埋め込む必要があります。XmlNamespaceManager を使って MSBuild の namespace オブジェクトを生成し、SelectNodes の第2引数に渡すようにします。そして xpath には追加した namespace の prefix を付けます。

$proj = [xml]Get-Content Target.csproj

$ns = New-Object Xml.XmlNamespaceManager $proj.NameTable
$ns.AddNamespace("msb", "http://schemas.microsoft.com/developer/msbuild/2003")

$nodes = $proj.SelectNodes("//msb:ItemGroup/msb:Reference[contains(./@Include , 'System')]", $ns)

foreach($node in $nodes) { Write-Host $node.Include }

出力結果

System
System.Core
System.Xml.Linq
System.Data.DataSetExtensions
System.Data
System.Deployment
System.Drawing
System.Net.Http
System.Windows.Forms
System.Xml

ちゃんと取れました。