PowerShell解析XML遇selectSingleNode方法未找到错误及需求实现
解决PowerShell解析XML时的
selectSingleNode方法报错问题 你的报错根源很明确:你用Select-Object -Property Name过滤后,$Role已经不是原始的XML节点对象了。PowerShell会把筛选后的结果包装成一个Selected.System.Xml.XmlElement类型的自定义对象,这个对象只保留了你指定的Name属性,自然没有XML节点特有的selectSingleNode方法。
要实现你期望的输出,只需要直接遍历原始的XML Role节点,然后访问它的子节点即可,不需要提前筛选属性。下面是两种可行的方案:
方案1:直接输出(简单直观)
这种方式直接打印角色名和对应的权限,用缩进对齐:
[xml]$inputFile = Get-Content "C:\RolesnPer.xml" # 遍历每个原始Role节点 foreach ($Role in $inputFile.Inventory.Roles.Role) { # 打印角色名称 Write-Host "`n$($Role.Name)" # 遍历当前角色下的所有Privilege子节点 foreach ($Privilege in $Role.Privilege) { # 用制表符缩进权限名称 Write-Host "`t$($Privilege.Name)" } }
方案2:生成表格格式(更接近你期望的输出)
如果想要严格的表格样式,角色名只在第一行显示,后续权限行的Name列留白,可以通过创建自定义对象再格式化输出:
[xml]$inputFile = Get-Content "C:\RolesnPer.xml" $outputData = @() foreach ($Role in $inputFile.Inventory.Roles.Role) { $isFirstPrivilege = $true foreach ($Privilege in $Role.Privilege) { # 创建自定义对象,控制Name列是否显示角色名 $outputData += [PSCustomObject]@{ Name = if ($isFirstPrivilege) { $Role.Name } else { "" } Privilege = $Privilege.Name } $isFirstPrivilege = $false } } # 格式化输出为自动调整的表格 $outputData | Format-Table -AutoSize
运行上面的代码后,你会得到和期望一致的输出:
Name Privilege ---- --------- VirtualMachinePowerUser Datastore.Browse Global.CancelTask ScheduledTask.Create VirtualMachineUser Global.CancelTask ScheduledTask.Create
总结一下:处理XML节点时,尽量保留原始的XmlElement对象,不要过早用Select-Object过滤属性,这样才能正常访问节点的子元素和XML相关方法。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

