从XML中获取具有特定名称的所有节点的值

Sky*_*rdw 6 xml powershell

我在以最有效的方式从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>
Run Code Online (Sandbox Code Playgroud)

我想从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>
Run Code Online (Sandbox Code Playgroud)

并获得:

  • 论据一
  • 论点二
  • 论据三

有任何想法吗?到目前为止,我尝试做:

$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
...
Run Code Online (Sandbox Code Playgroud)

但这似乎不是最好的方法。应该有更好的东西。

Ans*_*ers 6

您在这里尝试做不同的事情,因此您将无法对两个操作使用完全相同的代码。

在第一个示例中,您要选择名称为的所有节点的值MyNode。选择带有XPath表达式 的节点//MyNode并展开其#text属性。有多种方法可以执行此操作,例如Select-Xml,使用@PetSerAl建议:

Select-Xml -XPath '//MyNode' -Path 'C:\path\to\first.xml' |
  Select-Object -Expand Node |
  Select-Object -Expand '#text'
Run Code Online (Sandbox Code Playgroud)

或通过将文件作为XmlDocument对象导入并使用其SelectNodes()方法:

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

在第二个示例中,您MyArgument要从具有该特定属性的所有节点中选择属性的值。使用XPath表达式//@MyArgument选择所有属性MyArgument,然后像以前一样扩展它们的值,如下所示:

Select-Xml -XPath '//@MyArgument' -Path 'C:\path\to\second.xml' |
  Select-Object -Expand Node |
  Select-Object -Expand '#text'
Run Code Online (Sandbox Code Playgroud)

或像这样:

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

边注:

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

[xml]$xml = Get-Content 'C:\path\to\your.xml'
Run Code Online (Sandbox Code Playgroud)

做同样的事情,所以不要使用两者之一。

  • 恕我直言,除了选择具有属性的元素外,您还可以自己选择属性:`// @ MyArgument`。 (2认同)