foreach-object if return,返回所有值问题

时间:2018-10-12 05:53:42

标签: powershell foreach

我正在生成这个奇怪的输出。 $ abc是一个具有约200个节点的xml 我尝试搜索主机名为cat01.pdx30的特定元素,但以下内容似乎从abc打印了所有主机名,有什么想法吗?

($abc.DeviceMetaData) | ForEach-Object { 
    if ($PSItem.Device.HostName -match  [regex]::Escape("cat01.pdx30")) {
        return $psitem.Device.HostName 
    }
}

$ abc看起来像这样:

<?xml version="1.0"?>
<DeviceMetaData xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Device HostName="cat02.pdx30">
    <Property Name="Home">Region</Property>
  </Device>
  <Device HostName="cat01.mwh01">
    <Property Name="AclFile" />
    <Property Name="AnchorPresent">False</Property>
    <Property Name="CloudType">Public</Property>
    <Property Name="ConfigTemplateFile">iper_Ce.xml</Property>
    <Property Name="DcCode">mwh01</Property>
  </Device>
  <Device HostName="ALB70-RME71-226-01OSP">
    <Property Name="OpticalEnabled">True</Property>
  </Device>
</DeviceMetaData>

2 个答案:

答案 0 :(得分:2)

根据数据样本,您没有指示Powershell处理DeviceMetaData元素的子元素

$abc.DeviceMetaData.Device | ForEach-Object { 
    if($_.HostName -match [regex]::Escape("cat01.pdx30")) {
        $PSItem.Hostname
    }
}

上面的示例告诉PowerShell遍历所有 Device 元素。对于这些对象,每个对象都将与HostName属性匹配,如果匹配,则仅输出HostName。

请考虑不要在PowerShell中使用 return 关键字。 return关键字中断了当前作用域的执行,这与仅输出某些数据完全不同。

请注意,您的样本数据和搜索条件不同。您的数据中没有任何“ cat01.pdx30” 主机名。只是为了避免您认为该解决方案不起作用。

更新 基于新的要求,该示例完成了预期的工作。

$abc.DeviceMetaData.Device | ForEach-Object {
    if($_.HostName -match [regex]::Escape("cat01.mwh01")) {
        $PSItem.Property | Where-Object Name -eq "DcCode" | Select-Object "#text"
    }
}

在新示例中,我们遍历所有 Property 元素,使用 Where-Object 对其进行过滤,并选择带有 magical < / em>“ #text”,指示powershell读取属性的值,而不是具有名称和值的属性。

答案 1 :(得分:0)

使用XPath的其他方法:

[xml] $xml=get-content "C:\temp\test.xml"
$xml.SelectNodes('//DeviceMetaData/Device[@HostName="cat01.mwh01"]/Property[@Name="DcCode"]')."#text"