在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 
+0

谢谢,这个作品。我仍然困惑,为什么我的例子中的Where-Object没有。 – MvdD