如何在PowerShell中提取具有相同子名称但值不同的子节点?

时间:2019-04-29 20:30:34

标签: powershell xml-parsing

在XML文件中,有一些子节点具有相同的节点名称,但是具有不同的值,如从示例中可以看到的那样。

我已经尝试过可以在互联网上找到的内容,但是,没有任何效果。而且,我是PowerShell的新手,我已经看到它确实很强大,但是这很难,因为您在示例中可以看到一个特定的子节点。

chdir('\\folder')
[xml]$XmlDocument = Get-Content "football.xml"

第一次尝试:

foreach ($s in $XmlDocument.entities.entity.ext) {
    $attribs = $s.Attributes
    if ($attribs = 'Alias') {
        $s
    }
}

不知道我在这里做什么,但是我试图遍历文件以获取<ext>子节点内子节点“别名”的值。

然后我尝试了以下操作:

$XmlDocument.SelectNodes("//entities/entity/ext") | ForEach Object {
    New-Object -Type PSObject -Property @{
        Name  = $s_.name
        Alias = $s_.alias
    }
}

但是这也不起作用。我还尝试将所有内容导出到CSV:

$XmlDocument.entities.ChildNodes |
    Export-Csv "footballers.csv" -NoTypeInformation -Delimiter:";" -Encoding:UTF8

这确实工作得很好,但是<ext>子节点的输出是汇总错误消息。

所以输入如下。可以看出,<ext>节点也不是均匀分布的,这更加困难。有时某个实体中有某些<ext>节点,有时则没有。

<entities>
    <entity id="1" version="1928">
        <name>Ronaldo, Cristiano</name>
        <datebirth>02/05/1985</datebirth>
        <country>Portugal</country>
        <ext name="Alias">Ronnie</ext>
        <ext name="Height">187</ext>
        <ext name="Nationality">Portuguese</ext>
        <ext name="Club">Juventus</ext>
        <ext name="Previously">Real Madrid</ext>
        <ext name="Brand">CR7</ext>
    </entity>
    <entity id="24" version="1928">
        <name>Messi, Lionel</name>
        <datebirth>06/24/1987</datebirth>
        <country>Argentina</country>
        <ext name="Alias">La Pulga</ext>
        <ext name="Height">170</ext>
        <ext name="Nationality">Argentine</ext>
        <ext name="Club">FC Barcelona</ext>
    </entity>
</entities>

然后我想将所有这些转换为CSV文件,并在输出中包含所有信息。

2 个答案:

答案 0 :(得分:1)

您的第二次尝试将您带到了那里,但是您拥有的XPath表达式正在选择所有<ext>节点。您想要的是一个表达式,该表达式选择所有<entity>个节点,这些节点包含一个子节点<ext>,该子节点的属性name的值为Alias

//entities/entity[ext[@name='Alias']]

然后您可以像这样构建自定义对象:

New-Object -Type PSObject -Property @{
    Name  = $_.name
    Alias = $_.SelectSingleNode("./ext[@name='Alias']").'#text'
}

答案 1 :(得分:0)

无需使用XPath,这应该可以工作:

[xml]$XmlDocument = Get-Content "football.xml"

$data = foreach ($entity in $XmlDocument.entities.entity) {
    [PSCustomObject]@{
        'Name' = $entity.name
        'Alias' = ($entity.ext | Where-Object { $_.name -eq 'Alias' }).InnerText   # or use .'#text'
    }
}

$data | Export-Csv -Path '<PATH AND FILENAME FOR THE EXPORTED CSV FILE' -NoTypeInformation -Delimiter ';' -Encoding UTF8

$data将包含一组PSCustomObject,您可以轻松将它们导出到CSV文件。
当输出到控制台时,它将如下所示:

Name               Alias   
----               -----   
Ronaldo, Cristiano Ronnie  
Messi, Lionel      La Pulga