如何用PowerShell匹配XML的DefaultId并获取对应DID的Size属性
XML节点匹配问题分析与解决
场景与问题描述
给定如下结构的XML文件:
<?xml version="1.0" encoding="utf-8"?> <Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Physicals> <Physical> <Model>6900</Model> <DefaultId>19</DefaultId> <IDs> <DID Size="6x8" ID="19" /> </IDs> </Physical> <Physical> <Model>dl2100</Model> <DefaultId>8</DefaultId> <IDs> <DID Size="A4" ID="6" /> <DID Size="LETTER" ID="8" /> </IDs> </Physical> </Physicals> </Configuration>
需求是:遍历每个Physical节点,匹配DefaultId值,找到对应IDs下ID属性与DefaultId相等的DID节点,并输出其Size属性。
最初编写的PowerShell代码因使用赋值运算符=而非比较运算符-eq报错:
[xml]$xml = [xml](Get-Content C:\Users\me\configured.xml) $Physicals = $xml.SelectNodes('//Physicals/Physical') foreach($p in $Physicals) { $p.Model $id = $p.DefaultId if($p.IDs.DID.ID=$id) # 此处错误:赋值而非比较 { $p.IDs.DID.Size } }
报错信息:The property ID cannot be found on this object。
将=改为-eq后,代码执行结果不符合预期:对于dl2100模型,本应仅返回LETTER,却同时返回A4和LETTER。
问题原因
当IDs节点下存在多个DID子节点时,$p.IDs.DID会返回一个节点集合而非单个节点:
$p.IDs.DID.ID会生成包含所有DID节点ID属性的数组(如示例中为@(6,8))- 使用
$p.IDs.DID.ID -eq $id时,会返回一个布尔数组(如@($false, $true)) - PowerShell的
if语句只要数组中存在至少一个$true就会执行代码块,此时$p.IDs.DID.Size会输出所有DID节点的Size属性,而非匹配的单个节点。
解决方法
方法1:遍历DID节点逐一匹配
直接遍历每个Physical下的DID节点,判断ID属性是否等于DefaultId:
[xml]$xml = [xml](Get-Content C:\Users\me\configured.xml) $Physicals = $xml.SelectNodes('//Physicals/Physical') foreach($p in $Physicals) { Write-Host "Model: $($p.Model)" $targetId = $p.DefaultId # 遍历当前Physical下的所有DID节点 foreach($did in $p.IDs.DID) { if($did.ID -eq $targetId) { Write-Host "Matched Size: $($did.Size)" } } }
方法2:使用XPath直接筛选匹配节点
利用XPath表达式直接定位到符合条件的DID节点,无需额外遍历:
[xml]$xml = [xml](Get-Content C:\Users\me\configured.xml) $Physicals = $xml.SelectNodes('//Physicals/Physical') foreach($p in $Physicals) { Write-Host "Model: $($p.Model)" $targetId = $p.DefaultId # 用XPath筛选ID属性等于targetId的DID节点 $matchedDid = $p.SelectSingleNode("./IDs/DID[@ID='$targetId']") if($matchedDid) { Write-Host "Matched Size: $($matchedDid.Size)" } }
此方法更高效,尤其是在XML节点数量较多时。
内容的提问来源于stack exchange,提问作者Michele
相关产品推荐
相关产品推荐

