如何在 Powershell 中迭代 Xml.XmlElement 的不规则命名的子元素?
我有一个以下格式的 XML 文件:
<xml>
<data>
<foo float="99.0"/>
<bar float="12.0"/>
<tribble bool="true"/>
...
<flibble int="1"/>
</data>
</xml>
如果我在 Powershell 中获取该数据,我可以使用 Get-Memeber 查看数据的所有子元素:
> $xmlData = [xml](Get-Content myfile.xml)
> $xmlData.data | Get-Member
...
foo Property System.Xml.XmlElement ...
bar Property System.Xml.XmlElement ...
tribble Property System.Xml.XmlElement ...
...
并且我可以单独访问每个子元素。但是我如何迭代所有的子项,并用管道处理它们呢?我很想能够写出这样的东西:
> $xmlData.data.Children | ?{$_ -eq "foo"}
……但可惜这只是一厢情愿的想法。
编辑:好的,所以我可以反思这样的属性:
> $xmlData.data | get-member -memberType Property | ?{$_.Name -eq "foo"}
但是我不能从属性(上面我正在对 MemberDefinition 进行操作)转到实际的子元素。或者我可以吗?
I have an XML file of the following format:
<xml>
<data>
<foo float="99.0"/>
<bar float="12.0"/>
<tribble bool="true"/>
...
<flibble int="1"/>
</data>
</xml>
If I fetch that data in Powershell, I can see all the child elements of data with a Get-Memeber:
> $xmlData = [xml](Get-Content myfile.xml)
> $xmlData.data | Get-Member
...
foo Property System.Xml.XmlElement ...
bar Property System.Xml.XmlElement ...
tribble Property System.Xml.XmlElement ...
...
And I can access each child element individually. But how would I iterate over all the children, processing them with pipes? I'd love to be able to write something like this:
> $xmlData.data.Children | ?{$_ -eq "foo"}
...But alas that's just wishful thinking.
EDIT: Ok so I can reflect on the properties like this:
> $xmlData.data | get-member -memberType Property | ?{$_.Name -eq "foo"}
But I can't then go from the property (above I'm operating on a MemberDefinition) to the actual child element. Or can I?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先:您需要使用
Get-Member -Force
...它将向您显示一切。请特别注意 get_* 方法,这些方法表示由于某种原因未在 PowerShell 中作为属性公开的属性。因此,当您在成员列表中看到get_ChildNodes
时,这意味着该对象上有一个 .ChildNodes 属性(即使 PowerShell 由于某种原因隐藏了它)。第二:因此,有很多方法,包括您暗示的 get-member 方法(我附加
Format-Table
因为它更容易告诉您得到一些东西):$xmlData.data.SelectNodes("*") | ft 名称,OuterXml
$xmlData.data.ChildNodes | ft 名称,OuterXml
$xmlData.data | gm型属性| % { $xmlData.data.($_.Name) } |
其中 { $_ -is [Xml.XmlElement] } | ft 名称,OuterXml
First: You need to use
Get-Member -Force
... which will show you everything. Note with particular interest the get_* methods which represent properties which for some reason aren't exposed as properties in PowerShell. So when you seeget_ChildNodes
in the member list, it means there's a .ChildNodes property on the object (even though PowerShell hides it for some reason).Second: So therefore, there are lots of ways, including the get-member method you hinted at (I append the
Format-Table
because it makes it easier to tell that you got something):$xmlData.data.SelectNodes("*") | ft name, OuterXml
$xmlData.data.ChildNodes | ft name, OuterXml
$xmlData.data | gm -type Property | % { $xmlData.data.($_.Name) } |
Where { $_ -is [Xml.XmlElement] } | ft Name, OuterXml
由于某种原因,
Get-Member
不显示System.Xml.XmlElement
提供的其他属性。以下是完整的成员列表: http://msdn.microsoft .com/en-us/library/system.xml.xmlelement_members.aspx如您所见,有一个
ChildNodes
属性,因此您可以执行以下操作:(Select- Xml -Path "file.xml" -XPath "//xml/data").Node.ChildNodes | Where-Object { $_.Name -eq "foo" }
For some reason
Get-Member
doesn't display the other propertiesSystem.Xml.XmlElement
provides. Here is the full member list: http://msdn.microsoft.com/en-us/library/system.xml.xmlelement_members.aspxAs you can see, there is a
ChildNodes
property, so you can do this:(Select-Xml -Path "file.xml" -XPath "//xml/data").Node.ChildNodes | Where-Object { $_.Name -eq "foo" }