Read XML Attribute values based on another attribute value in the same node using Powershell

吃可爱长大的小学妹 提交于 2021-01-29 07:43:44

问题


I have a XML file file1.xml which has the data like below.

<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>

I Need a PowerShell script which will return the value of the Path attribute based on the Name attribute value.

Example:

If I pass the value "File4.rdl" it should return the value as "Folder76".

I Wrote the command to read the XML data and stored the data in an array $Test.

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

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

Write-Host $Test

I Wrote the below PowerShell script to perform the same.

$AttribureReportName = "File4.rdl"

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

As I have too many XML tags it was taking long time perform the operation. Is there any better way to do the same?


回答1:


First off, this is wrong:

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

Don't load XML files this way, this can cause encoding issues. XML parsers have a well thought-out automatic encoding detection mechanism. Get-Content does not have that, so there is a good chance that the XML file is loaded with the wrong encoding and data inside gets corrupted.

Use the XML parser to load the file.

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

After that, you can use XPath to pick the right node from the file. This will be much faster than writing any Powershell loops yourself (Where-Object also is a loop).

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



回答2:


As your Name attribute should be compared in a Case-Insensitive mode, I suggest something like this:

[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
}


来源:https://stackoverflow.com/questions/54214951/read-xml-attribute-values-based-on-another-attribute-value-in-the-same-node-usin

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!