在XML子节点上过滤
问题描述:
我正在尝试处理MSBuild
文件,以便使用下面的PowerShell代码段来提取Include
属性中的文件名。在XML子节点上过滤
Get-ChildItem $xmlFile |
ForEach-Object { Write-Host $_.FullName; [xml](Get-Content $_) } |
Where-Object {
(($_.Project.ItemGroup -ne $null) -and
($_.Project.ItemGroup.ProjectFile -ne $null))
} -ErrorAction SilentlyContinue |
ForEach-Object { $_.Project.ItemGroup.ProjectFile } |
Where-Object { ($_.Include -ne $null) } |
ForEach-Object { Write-Host $_ }
这工作得很好XML有这样的ItemGroup
子元素:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="settings.props" />
<ItemGroup>
<ProjectFile Include="filename.proj"/>
但是,当XML层次是不同的(无ItemGroup
元),如下面的脚本失败,出现错误:
The property 'ItemGroup' cannot be found on this object. Verify that the property exists.
即使是ErrorAction
也不会抑制错误输出。
如何在管道中检查子元素是否存在并跳过其中没有的文件?此外,为什么-ErrorAction
参数不起作用?
答
你不需要负载使用Get-Content文件,投它xml
并尝试通过自己选择的节点。
Get-ChildItem $xmlFile | ForEach-Object {
$node = Select-Xml -Path $_.FullName `
-XPath '/n:Project/n:ItemGroup/n:ProjectFile/@Include' `
-Namespace @{n = 'http://schemas.microsoft.com/developer/msbuild/2003'}
if ($node)
{
$node.Node.Value
}
}
它是采用xpath
选择Include
属性(和namespace
):只需使用Select-XML cmdlet的。
输出:
filename.proj
谢谢,这个作品。我仍然困惑,为什么我的例子中的Where-Object没有。 – MvdD