【问题标题】:Read XML Attribute values based on another attribute value in the same node using Powershell使用 Powershell 根据同一节点中的另一个属性值读取 XML 属性值
【发布时间】:2019-01-16 19:48:45
【问题描述】:

我有一个 XML 文件 file1.xml,其中包含如下数据。

<Tag1>
<Tag2>      
  <file Name="file1.rdl" Path="folder34" />
  <File Name="file2.rdl" Path="folder37" />
  <File Name="file3.rdl" Path="folder34" />
  <File Name="File4.rdl" Path="folder76" />
  <File Name="file5.rdl" Path="folder37" />
</Tag2>
</Tag1>

我需要一个 PowerShell 脚本,它将根据 Name 属性值返回 Path 属性的值。

例子:

如果我传递值“File4.rdl”,它应该将值返回为“Folder76”。

我编写了读取 XML 数据的命令,并将数据存储在数组 $Test 中。

[xml]$XmlDocument = Get-Content "D:\Roshan\Testing\Test1.xml"

$Test = $XmlDocument.Tag1.Tag2.file | Select-Object Name, Path

Write-Host $Test

我编写了下面的 PowerShell 脚本来执行相同的操作。

$AttribureReportName = "File4.rdl"

foreach ($item in $Test) {
    if ($item.Name -eq $AttribureReportName) {
        $FinalFolder = $item.Path
        Write-Output $FinalFolder 
    }
}

由于我有太多 XML 标记,因此执行该操作需要很长时间。有没有更好的方法来做同样的事情?

【问题讨论】:

    标签: xml powershell


    【解决方案1】:

    首先,这是错误的:

    [xml]$XmlDocument = Get-Content "D:\Roshan\Testing\Test1.xml"
    

    不要以这种方式加载 XML 文件,这可能会导致编码问题。 XML 解析器有一个经过深思熟虑的自动编码检测机制。 Get-Content 没有这个,所以很有可能 XML 文件加载了错误的编码并且里面的数据被破坏了。

    使用 XML 解析器加载文件。

    $XmlDocument = New-Object xml
    $XmlDocument.Load("D:\Roshan\Testing\Test1.xml")
    

    之后,您可以使用 XPath 从文件中选择正确的节点。这将比自己编写任何 Powershell 循环快得多(Where-Object 也是一个循环)。

    $File = $XmlDocument.SelectSingleNode("/Tag1/Tag2/File[@Name = 'File4.rdl']")
    Write-Host $File.Path
    

    【讨论】:

    • 能否请您举一个小例子来说明如何使用“where-object” plz?
    • @Roshan 将SelectSingleNode() 与 XPath 表达式一起使用是您问题中描述的问题的适当解决方案。
    【解决方案2】:

    由于您的Name 属性应该在不区分大小写的模式下进行比较,我建议这样:

    [xml]$xml = @"
    <Tag1>
    <Tag2>      
      <file Name="file1.rdl" Path="folder34" />
      <File Name="file2.rdl" Path="folder37" />
      <File Name="file3.rdl" Path="folder34" />
      <File Name="File4.rdl" Path="folder76" />
      <File Name="file5.rdl" Path="folder37" />
    </Tag2>
    </Tag1>
    "@
    
    $AttribureReportName = "File4.rdl"
    
    foreach ($item in ($xml.Tag1.Tag2.file | Where-Object {$_.Name -eq $AttribureReportName})) {
        $item.Path
    }
    

    【讨论】:

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