【问题标题】:Filter on XML child nodes过滤 XML 子节点
【发布时间】:2016-06-08 01:09:30
【问题描述】:

我正在尝试使用下面的 PowerShell sn-p 处理 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 元素),如下所示,脚本失败并出现错误:

在此对象上找不到属性“ItemGroup”。验证该属性是否存在。

即使ErrorAction 也不会抑制错误输出。

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

【问题讨论】:

    标签: xml powershell msbuild


    【解决方案1】:

    你不需要使用Get-Content加载文件,cast它到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
    

    【讨论】:

    • 谢谢,这行得通。仍然对为什么我的示例中的 Where-Object 没有感到困惑。
    猜你喜欢
    • 2011-06-02
    • 1970-01-01
    • 1970-01-01
    • 2021-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多