2015-12-29 2 views
1

У меня возникла проблема с наиболее эффективным способом получения всех значений узлов с определенным именем из XML.Получение значений из всех узлов с определенным именем из XML

Например:

<h1> 
<MyNode>Node One</MyNode> 
<h2> 
    <MyNode>Note Two</MyNode> 
    <DiffrentNode>I dont want that</DiffrentNode> 
    <h3> 
     <MyNode>Node Three</MyNode> 
    </h3> 
</h2> 
<HHH1> 
    <MyNode>Node Four</MyNode> 
</HHH1> 
</h1> 
<g2> 
    <MyNode>Node Five</MyNode> 
</g2> 

Из XML Я хочу, чтобы получить эти значения:

  • Узел Один
  • Узел Два
  • Узел Три
  • Узел Четыре
  • Узел Пять

Я хотел бы быть в состоянии сделать то же самое с кодом вроде этого:

<h1> 
<h2 MyArgument = "Argument One" Stuff = "I dont want that"> 
    <DiffrentNode>Something I dont want</DiffrentNode> 
    <h3 MyArgument = "Argument Two" Stuff = "I dont want that too"> 
    </h3> 
</h2> 
<HHH1> 
    <DiffrentNode>Something I dont want</DiffrentNode> 
</HHH1> 
</h1> 
<g2 MyArgument = "Argument Three"> 
    <DiffrentNode>Something I dont want</DiffrentNode> 
</g2> 

и получите:

  • Довод Один
  • Довод Два
  • Довод Три

Любые идеи? До сих пор я пробовал делать:

$xdoc = New-Object System.Xml.XmlDocument 
$file = Resolve-Path("C:\CompiledDynoview.xml") 
$xdoc.load($file) 
[xml] $xdoc = Get-Content $file 
$xdoc.h1.MyNode 
$xdoc.h1.h2.MyNode 
$xdoc.h1.h3.MyNode 
... 

Но это не похоже на лучший способ. Должно быть что-то лучше.

+3

'Select-Xml -XPath '// MyNode' -Path 'C: \ CompiledDynoview.xml'' – PetSerAl

ответ

3

Вы пытаетесь сделать здесь разные вещи, поэтому вы не сможете использовать тот же самый код для обеих операций.

В первом примере вы хотите выбрать значение всех узлов с именем MyNode. Выберите узлы с XPath expression//MyNode и разместите их #text. Есть различные способы сделать это, например, с Select-Xml, как это было предложено @PetSerAl:

Select-Xml -XPath '//MyNode' -Path 'C:\path\to\first.xml' | 
    Select-Object -Expand Node | 
    Select-Object -Expand '#text' 

или импортировать файл в качестве XmlDocument объекта и используя его SelectNodes() метод:

[xml]$xml = Get-Content 'C:\path\to\first.xml' 
$xml.SelectNodes('//MyNode') | Select-Object -Expand '#text' 

В вашей второй Например, вы хотите выбрать значение атрибута MyArgument со всех узлов, имеющих этот конкретный атрибут.Используйте выражение XPath //@MyArgument, чтобы выбрать все атрибуты MyArgument, а затем разверните их значение, как и раньше, как это:

Select-Xml -XPath '//@MyArgument' -Path 'C:\path\to\second.xml' | 
    Select-Object -Expand Node | 
    Select-Object -Expand '#text' 

или как это:

[xml]$xml = Get-Content 'C:\path\to\second.xml' 
$xml.SelectNodes('//@MyArgument') | Select-Object -Expand '#text' 

примечание стороны:

$xml = New-Object System.Xml.XmlDocument 
$xml.load('C:\path\to\your.xml') 

и

[xml]$xml = Get-Content 'C:\path\to\your.xml' 

делайте то же самое, поэтому используйте тот или иной, а не тот и другой.

+1

IMHO, вместо выбора элементов с атрибутом вы можете просто выбрать атрибуты сами:' // @ MyArgument'. – PetSerAl

+0

@PetSerAl Действительно, вы можете. Я думал, что испытал это до публикации, но, видимо, я этого не сделал. Спасибо за головы. Обновленный ответ соответственно. –