如何用PowerShell筛选XML中Dilbert节点下TTT的Default和CurrentValue
问题描述
尝试读取XML文档,仅获取Dilbert节点下TTT子节点的Default和CurrentValue的名称与对应值,但当前PowerShell代码输出了Dilbert节点下所有子节点的相关值,无法缩小范围。
当前代码
[xml]$doc = Get-Content c:\Temp\TTTOrderSettings.xml foreach($key in $doc.Configuration.Key) #foreach($key in $doc.Configuration.Key.Key) { if( ($key.Name -eq "Dilbert") ) { if($key.Key.Name -eq "TTT") { #Key = $key.Name #Value = $key.Value echo $key.Key.Name echo $key.Key.Value #echo $key.Key.Name.Default } }
当前输出
Selection TTT Front Preview Priority Finish RedFaced Name #text ---- ----- Default SelectManual CurrentValue SelectManual Default Enhanced CurrentValue Enhanced Default False CurrentValue False Default True CurrentValue True Default PriorityASAP CurrentValue PriorityASAP Default Fabulous CurrentValue Fabulous Default false CurrentValue False
XML文件内容
<?xml version="1.0" encoding="utf-16"?> <Configuration> <Key Name="Archive"> <Key Name="Selection"> <Value Name="Default">SelectAll</Value> <Value Name="CurrentValue">SelectAll</Value> </Key> <Key Name="Front"> <Value Name="Default">False</Value> <Value Name="CurrentValue">False</Value> </Key> <Key Name="Preview"> <Value Name="Default">True</Value> <Value Name="CurrentValue">True</Value> </Key> <Key Name="Priority"> <Value Name="Default">PriorityASAP</Value> <Value Name="CurrentValue">PriorityASAP</Value> </Key> <Key Name="Finish"> <Value Name="Default">Fabulous</Value> <Value Name="CurrentValue">Fabulous</Value> </Key> <Key Name="RedFaced"> <Value Name="Default">false</Value> <Value Name="CurrentValue">false</Value> </Key> </Key> <Key Name="Batch"> <Key Name="TTT"> <Value Name="Default">Off</Value> <Value Name="CurrentValue">Off</Value> </Key> <Key Name="Front"> <Value Name="Default">False</Value> <Value Name="CurrentValue">False</Value> </Key> <Key Name="Preview"> <Value Name="Default">True</Value> <Value Name="CurrentValue">True</Value> </Key> <Key Name="Priority"> <Value Name="Default">PriorityASAP</Value> <Value Name="CurrentValue">PriorityASAP</Value> </Key> <Key Name="Finish"> <Value Name="Default">Fabulous</Value> <Value Name="CurrentValue">Fabulous</Value> </Key> <Key Name="RedFaced"> <Value Name="Default">false</Value> <Value Name="CurrentValue">false</Value> </Key> <Key Name="Scan"> <Value Name="Default">Medium</Value> <Value Name="CurrentValue">Medium</Value> </Key> <Key Name="Type"> <Value Name="Default">bed</Value> <Value Name="CurrentValue">bed</Value> </Key> </Key> <Key Name="Dilbert"> <Key Name="Selection"> <Value Name="Default">SelectManual</Value> <Value Name="CurrentValue">SelectManual</Value> </Key> <Key Name="TTT"> <Value Name="Default">Enhanced</Value> <Value Name="CurrentValue">Enhanced</Value> </Key> <Key Name="Front"> <Value Name="Default">False</Value> <Value Name="CurrentValue">False</Value> </Key> <Key Name="Preview"> <Value Name="Default">True</Value> <Value Name="CurrentValue">True</Value> </Key> <Key Name="Priority"> <Value Name="Default">PriorityASAP</Value> <Value Name="CurrentValue">PriorityASAP</Value> </Key> <Key Name="Finish"> <Value Name="Default">Fabulous</Value> <Value Name="CurrentValue">Fabulous</Value> </Key> <Key Name="RedFaced"> <Value Name="Default">false</Value> <Value Name="CurrentValue">False</Value> </Key> </Key> <Key Name="Flimsy"> <Key Name="Softy"> <Value Name="Default">true</Value> <Value Name="CurrentValue">True</Value> </Key> <Key Name="OrderType"> <Value Name="Default">OrderTypeNew</Value> <Value Name="CurrentValue">OrderTypeNew</Value> </Key> <Key Name="Resolution"> <Value Name="Default">Medium</Value> <Value Name="CurrentValue">Medium</Value> </Key> <Key Name="Boastable"> <Value Name="Default">false</Value> <Value Name="CurrentValue">False</Value> </Key> <Key Name="Type"> <Value Name="Default">Full</Value> <Value Name="CurrentValue">Full</Value> </Key> <Key Name="TTT"> <Value Name="Default">Enhanced</Value> <Value Name="CurrentValue">Enhanced</Value> </Key> <Key Name="Front"> <Value Name="Default">False</Value> <Value Name="CurrentValue">False</Value> </Key> <Key Name="Preview"> <Value Name="Default">True</Value> <Value Name="CurrentValue">True</Value> </Key> <Key Name="Priority"> <Value Name="Default">PriorityASAP</Value> <Value Name="CurrentValue">PriorityASAP</Value> </Key> <Key Name="Finish"> <Value Name="Default">Fabulous</Value> <Value Name="CurrentValue">Fabulous</Value> </Key> <Key Name="RedFaced"> <Value Name="Default">false</Value> <Value Name="CurrentValue">false</Value> </Key> <Key Name="Included"> <Value Name="Default">true</Value> <Value Name="CurrentValue">true</Value> </Key> </Key> </Configuration>
解决方案
可以通过两种方式精准定位目标节点:
方法一:使用XPath直接查询
XPath是XML文档查询的高效方式,能直接定位到Dilbert下的TTT节点,再提取其Value子节点:
[xml]$doc = Get-Content c:\Temp\TTTOrderSettings.xml # 用XPath定位目标节点 $tttNode = $doc.SelectSingleNode("//Key[@Name='Dilbert']/Key[@Name='TTT']") # 输出Default和CurrentValue $tttNode.Value
方法二:优化循环逻辑
原代码的问题在于,当$key.Name -eq "Dilbert"时,$key.Key是Dilbert下的所有子Key节点集合,直接判断$key.Key.Name -eq "TTT"不符合预期,需要遍历该集合:
[xml]$doc = Get-Content c:\Temp\TTTOrderSettings.xml foreach($parentKey in $doc.Configuration.Key) { if($parentKey.Name -eq "Dilbert") { # 遍历Dilbert下的所有子Key节点 foreach($childKey in $parentKey.Key) { if($childKey.Name -eq "TTT") { # 输出TTT节点下的Value $childKey.Value break # 找到目标后退出循环,提升效率 } } } }
预期输出
两种方法都会得到如下结果:
Name #text ---- ----- Default Enhanced CurrentValue Enhanced
内容的提问来源于stack exchange,提问作者Michele
相关产品推荐
相关产品推荐

