基于父级信息的Powershell XML选择节点

时间:2018-07-16 14:41:11

标签: xml powershell foreach

我正在编写一个powershell脚本,在该脚本中,我需要根据父级的信息(属性名称,id的..)来获取某个节点的值

示例:

<?xml version="1.0" encoding="UTF-8"?>
<GrandParent>
    <Parent id="1">
        <foo></foo>
        <bar></bar>
        <buzz></buzz>
        <Child Name="correct">
            <Content>Value1</Content>
        </Child>
        <Child Name="wrong">
            <Content>Value2</Content>
        </Child>
        <Child Name="wrong">
            <Content>Value3</Content>
        </Child>
    </Parent>
    <Parent id="2">
        <foo></foo>
        <bar></bar>
        <buzz></buzz>
        <Child Name="correct">
            <Content>Value4</Content>
        </Child>
        <Child Name="wrong">
            <Content>Value5</Content>
        </Child>
        <Child Name="wrong">
            <Content>Value6</Content>
        </Child>
    </Parent>
    <Parent id="3">
        <foo></foo>
        <bar></bar>
        <buzz></buzz>
        <Child Name="correct">
            <Content>Value7</Content>
        </Child>
        <Child Name="wrong">
            <Content>Value8</Content>
        </Child>
        <Child Name="wrong">
            <Content>Value9</Content>
        </Child>
    </Parent>
</GrandParent>

我想得到一些输出,例如: 父级1:value1 父级2:value4 父级3:value7

说明:对于每个父节点,我要查看具有“正确”名称的“子”节点并获取其子的值

我正在ForEach-Object内循环使用ForEach-Object,但是我的上下文“ $ _”始终引用整个xml,而不是当前作用域:

$total_xml.GrandParent.Parent | ForEach-Oject {
   $_.Parent.Child | ForEach-Object{
      $_ #This refers back to the total_xml
   }
}

PS:我是Powershell脚本的新手:(

有人可以帮我提供一个简单的脚本吗?

2 个答案:

答案 0 :(得分:0)

以您的示例为例:

[xml] $xml = Get-Content -Path .\test.xml

您可以获得所需的输出:

Parent 1: value1
Parent 2: value4
Parent 3: value7

像这样:

$Parents = @($xml.GrandParent.Parent)
for ($i = 0; $i -lt $Parents.Count; $i++) {
    "Parent ${i}: " + @($Parents[$i].Child).Where{$_.Name -eq 'Correct'}.Content
}

或使用ForEach-Object(没有注意到父母的身份证):

$xml.GrandParent.Parent |
    ForEach-Object {
        "Parent $($_.id): " + @($_.Child).Where{$_.Name -eq 'Correct'}.Content
    }

答案 1 :(得分:0)

这不是最佳做法,但我喜欢它,因为它易于阅读。

$xml = new-object -typename xml
$xml.Load("C:\temp\le.xml")
#To get stuff
$xml.GrandParent.Parent | Where-Object {$_.id -like 1}
#To edit stuff
($xml.GrandParent.Parent | Where-Object {$_.id -like 1}).foo = "test"
#To save stuff
$xml.Save("C:\temp\le.xml")