2016-01-04 2 views
1

Вот мой пример XML:Перебора дочерних узлы

<root> 
    <Countries> 
    <Country Name="USA"> 
     <MyFilters> 
      <Filter>aaa</Filter> 
      <Filter>bbb</Filter> 
      <Filter>ccc</Filter> 
      <Filter>ddd</Filter> 
     </MyFilters> 
    </Country> 
    </Countries> 
</root> 

Я пытаюсь Переберите каждый <Filter> тега и использовать его значение - «ааа», «BBB», & hellip; для моего последующего процесса в PowerShell. Я использую XPath для доступа к этим значениям.

Вот мой сценарий:

[xml]$config_xml = Get-Content $config_path 
$Country = $config_xml.selectnodes('/root/Countries/Country[@Name = "USA"]/MyFilters') 
foreach ($Filter in $Country) { 
    Write-Host $Filter.InnerText 
} 

Но это выводит меня все <Filter> значения в одной строке, например так: aaa bbb ccc ddd. Как использовать мой XPath для получения одного фильтра за раз? Или есть способ конвертировать этот вывод в объект массива PowerShell, который я могу снова зацикливать?

ответ

2

v3 +

## Replace me with 
#[xml]$config_xml = Get-Content $config_path 
[xml]$config_xml = @' 
<root> 
    <Countries> 
    <Country Name="USA"> 
     <MyFilters> 
      <Filter>aaa</Filter> 
      <Filter>bbb</Filter> 
      <Filter>ccc</Filter> 
      <Filter>ddd</Filter> 
     </MyFilters> 
    </Country> 
    </Countries> 
</root> 
'@ 

($config_xml.root.Countries.Country| Where-Object Name -EQ USA).MyFilters.Filter 
+0

Спасибо за ваш ответ. Я получаю XML-содержимое следующим образом - [xml] $ config_xml = Get-Content $ config_path и сохраняя его в объекте XML. Не могли бы вы рассказать мне, что происходит в вашем примере? И как я могу использовать мой путь к файлу XML здесь? – jeevag

+0

надеюсь, что теперь ясно, –

+0

да, спасибо. – jeevag

0

Я просто понял, решение для этого, просто делюсь здесь, если кто-то нуждается в этом.

Я использовал child :: node() для извлечения всех дочерних узлов, а затем зациклился на этом.

$Country = $config_xml.selectnodes('/root/Countries/Country[@Name = "USA"]/MyFilters/child::node()') 
3

Ваш запрос XPath возвращает <MyFilters> узла, а не его дочерние узлы, поэтому InnerText является текстовым содержимым этого узла (то есть все дочерние узлы объединены).

Просто добавьте еще один шаг для ссылки Filter элементы, если вы хотите, чтобы петли через одну Filter в то время:

/root/Countries/Country[@Name = "USA"]/MyFilters/Filter 

или в случае, если дочерний элемент MyFilters может иметь различные названия, вы можете использовать *:

/root/Countries/Country[@Name = "USA"]/MyFilters/* 

Просто некоторые примечания. child - ось по умолчанию в XPath, поэтому /child::node() - это то же самое, что и /node(). И тогда node() возвращает все типы узлов (элемент, текст, комментарий и т. Д.), Поэтому * может быть более подходящим здесь, так как вы хотите только вернуть узлы элемента.

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