2016-06-08 5 views
2

Я пытаюсь обработать файлы MSBuild для извлечения имени файла в атрибуте Include с помощью фрагмента PowerShell ниже.Фильтр на дочерних узлах 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?

ответ

2

Вам не нужно нагрузки файл с помощью Get-Content, отливать его xml и попытаться выбрать узел самостоятельно. Просто используйте Select-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 для выбора атрибута Includenamespace).

Выход:

filename.proj 
+0

Спасибо, это работает. Все еще запутано, почему в Where-Object в моем примере нет. – MvdD

Смежные вопросы