我遇到了从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
...
但它似乎并不是最好的方式。应该有更好的东西。
答案 0 :(得分:5)
您尝试在此处执行不同的操作,因此您无法在两种操作中使用完全相同的代码。
在第一个示例中,您要选择名称为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'
做同样的事情,所以使用其中一个,而不是两个。