我有一个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标记太多,因此执行该操作需要花费很长时间。有没有更好的方法可以做到这一点?
答案 0 :(得分: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
}
答案 1 :(得分:2)
首先,这是错误的:
[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