过滤XML子节点

时间:2016-06-08 01:09:31

标签: xml powershell msbuild

我尝试使用下面的PowerShell代码段处理MSBuild文件以提取Include属性中的文件名。

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 $_ }

这适用于具有ItemGroup子元素的XML,如下所示:

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="settings.props" />
  <ItemGroup>
    <ProjectFile Include="filename.proj"/>

但是,当XML层次结构不同(没有ItemGroup元素)时,脚本会因错误而失败:

  

属性&#39; ItemGroup&#39;在这个对象上找不到。验证该属性是否存在。

即使ErrorAction也没有抑制错误输出。

如果子元素存在,我如何检查管道并跳过它不存在的文件?而且,为什么-ErrorAction参数不起作用?

1 个答案:

答案 0 :(得分:2)

您不需要使用Get-Content 将文件加载到xml并尝试选择节点你自己。只需使用Select-XML cmdlet:

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)。

<强>输出

filename.proj