使用Powershell进行XML文件的手术性编辑

8

我正在使用Powershell处理csproj文件,以执行项目引用的大规模编辑。到目前为止,我已经通过以下代码成功编辑了 ProjectReferences 中 Include 属性的值:

    $projectXml = [xml](Get-Content $_.Project.FullName)
    Add-TfsPendingChange -edit $_.Project.FullName -ErrorAction Stop
    $projectXml | Select-Xml -namespace @{msb = "http://schemas.microsoft.com/developer/msbuild/2003"} -xpath "//msb:ProjectReference[msb:Project='$projectGuid']" | Select-Object -ExpandProperty Node | foreach { $_.Include = "$newPath" }
    $projectXml.Save($_.Project.FullName)

这样做可以替换适当的ProjectReferences上的Include属性,效果很好。但是会有许多其他“无害”的更改,例如将所有标签格式化为单独的行,例如
<FileUpgradeFlags></FileUpgradeFlags>变成了

<FileUpgradeFlags>
</FileUpgradeFlags>

有没有一种方法可以执行这样的编辑而没有这些副作用? 编辑:为了对任何以其他原因查找此帖子的人更清晰,请注意,Select-MsBuildXml只是我在Select-Xml周围编写的包装函数,它预加载msbuild命名空间参数,并在之后扩展节点属性。

我很好奇为什么额外的空格会对您造成问题。 - Andrew Shepherd
1
主要是因为它会增加审核更改的工作量,同时也会在源代码控制中引起不必要的混乱。在极端情况下,VS会选择将所有这些换行标签重新格式化为单行元素,从而在下次对csproj文档进行更改时再次引发混乱,并使两者陷入烦人的格式争夺中。 - bwerks
1
这个答案是否可以使用Select-XML而不是Select-MsBuildXml来展示,以使其更适用于其他人? - Nathan Hartley
很有趣,你提到这个问题,因为我认为我已经将它移植为通用版本了;我的Select-MsBuildXml cmdlet已经变得如此自然,以至于我忽略了它。它只是加载msbuild命名空间并扩展节点属性,没有什么特别的。我将其转换为Select-Xml。 - bwerks
1个回答

12

我在几年前进行了大量的VS项目操作。似乎直接创建XmlDocument并使用Load(而不是使用Get-Content并转换为XML)对我来说效果更好:

$path = "C:\temp\foo.csproj"
$proj = new-object system.xml.xmldocument
$proj.PreserveWhitespace = $true
$proj.Load($path)
...
$proj.Save($path)

更新 - 尝试在加载XML文档之前将PreserveWhitespace属性设置为true,如上所示。


谢谢你的提示,但不幸的是结果似乎是一样的。希望VS能够对非标准格式友好一些。 - bwerks
1
我更新了答案,包括在XmlDocument上设置PreserveWhitespace属性。这似乎有所帮助。 - Keith Hill
太好了!这将为我节省很多审查的麻烦。非常感谢你! - bwerks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接