我在文本文件中有这个XML文档:
<?xml version="1.0"?>
<Objects>
<Object Type="System.Management.Automation.PSCustomObject">
<Property Name="DisplayName" Type="System.String">SQL Server (MSSQLSERVER)</Property>
<Property Name="ServiceState" Type="Microsoft.SqlServer.Management.Smo.Wmi.ServiceState">Running</Property>
</Object>
<Object Type="System.Management.Automation.PSCustomObject">
<Property Name="DisplayName" Type="System.String">SQL Server Agent (MSSQLSERVER)</Property>
<Property Name="ServiceState" Type="Microsoft.SqlServer.Management.Smo.Wmi.ServiceState">Stopped</Property>
</Object>
</Objects>
我想遍历每个对象并找到DisplayName
和ServiceState
。我该怎么办?我已经尝试过各种各样的组合,并且正在努力解决这个问题。
我这样做是为了将XML变为变量:
[xml]$priorServiceStates = Get-Content $serviceStatePath;
其中$serviceStatePath
是上面显示的xml文件名。然后我想我可以做类似的事情:
foreach ($obj in $priorServiceStates.Objects.Object)
{
if($obj.ServiceState -eq "Running")
{
$obj.DisplayName;
}
}
在这个例子中,我想要一个用SQL Server (MSSQLSERVER)
答案 0 :(得分:37)
PowerShell具有内置的XML和XPath功能。 您可以将Select-Xml cmdlet与XPath查询一起使用,从而从XML对象中选择节点 .Node。'#text'来访问节点值。
[xml]$xml = Get-Content $serviceStatePath
$nodes = Select-Xml "//Object[Property/@Name='ServiceState' and Property='Running']/Property[@Name='DisplayName']" $xml
$nodes | ForEach-Object {$_.Node.'#text'}
或更短
[xml]$xml = Get-Content $serviceStatePath
Select-Xml "//Object[Property/@Name='ServiceState' and Property='Running']/Property[@Name='DisplayName']" $xml |
% {$_.Node.'#text'}
答案 1 :(得分:0)
您也可以在没有[xml]强制转换的情况下执行此操作。 (尽管xpath本身就是一个世界。https://www.w3schools.com/xml/xml_xpath.asp)
$xml = (select-xml -xpath / -path stack.xml).node
$xml.objects.object.property
或者仅此而已,xpath区分大小写。两者具有相同的输出:
$xml = (select-xml -xpath /Objects/Object/Property -path stack.xml).node
$xml
Name Type #text
---- ---- -----
DisplayName System.String SQL Server (MSSQLSERVER)
ServiceState Microsoft.SqlServer.Management.Smo.Wmi.ServiceState Running
DisplayName System.String SQL Server Agent (MSSQLSERVER)
ServiceState Microsoft.SqlServer.Management.Smo.Wmi.ServiceState Stopped