Reputation: 1053
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?
Upvotes: 0
Views: 170
Reputation: 338326
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
Upvotes: 2
Reputation: 61168
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
}
Upvotes: 2