如何在Powershell中迭代不规则命名的Xml.XmlElement子元素?

时间:2010-08-02 16:06:54

标签: xml powershell powershell-v2.0

我有一个格式如下的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上面操作)转到实际的子元素。或者我可以吗?

2 个答案:

答案 0 :(得分:7)

首先:您需要使用Get-Member -Force ...这将显示所有内容。请特别关注get_ *方法,这些方法表示由于某种原因未在PowerShell中作为属性公开的属性。因此,当您在成员列表中看到get_ChildNodes时,表示该对象上存在.ChildNodes属性(即使PowerShell由于某种原因隐藏了它)。

第二:因此,有很多方法,包括你暗示的get-member方法(我追加Format-Table,因为这样可以更容易地告诉你有什么东西):

  1. $xmlData.data.SelectNodes("*") | ft name, OuterXml
  2. $xmlData.data.ChildNodes | ft name, OuterXml
  3. $xmlData.data | gm -type Property | % { $xmlData.data.($_.Name) } |
    Where { $_ -is [Xml.XmlElement] } | ft Name, OuterXml

答案 1 :(得分:3)

由于某种原因,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" }