代码之家  ›  专栏  ›  技术社区  ›  Roshan N

使用PowerShell基于同一节点中的另一个属性值读取XML属性值

  •  0
  • Roshan N  · 技术社区  · 7 年前

    我有一个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脚本,它将返回 Path 基于的属性 Name 属性值。

    例子:

    如果我传递值“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标记,所以执行该操作需要很长时间。还有更好的方法吗?

    2 回复  |  直到 7 年前
        1
  •  2
  •   Tomalak    7 年前

    首先,这是错误的:

    [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
    
        2
  •  2
  •   Theo    7 年前

    作为你 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
    }
    
    推荐文章