【问题标题】:foreach-object if return , returning all value issueforeach-object if return ,返回所有值问题
【发布时间】:2018-10-12 05:53:41
【问题描述】:

我有这个奇怪的输出正在生成。 $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>

【问题讨论】:

  • 能否分享一个 XML 文件的 sn-p,让我们了解它的结构?
  • 请编辑您的问题并提供示例数据以供其他人查看必要的详细信息以帮助您解决问题。
  • 已在主线程上更新
  • 根据您的描述,您似乎正在尝试查找具有属性值的节点。请考虑查看这个现有问题:Select XML element by attribute value and add an element

标签: powershell foreach


【解决方案1】:

根据数据样本,您没有指示 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 "#text" 指示 powershell 读取属性的值,而不是带有名称和值的属性。

【讨论】:

  • 实际上我的目的是找到一个特定的设备说“cat01.pdx30”并返回DcCode值..我传递$abc.DeviceMetaData的原因
  • 您看到我在更新中分享的新示例了吗?
【解决方案2】:

其他方法,使用 XPath:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多