2013-08-29 44 views
27

我有一個文本文件,這個XML文檔:如何在PowerShell中迭代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> 

我想通過每一個對象進行迭代,找到DisplayNameServiceState。我會怎麼做?我嘗試了各種組合,並努力解決它。

我這樣做是爲了讓XML到一個變量:

[xml]$priorServiceStates = Get-Content $serviceStatePath;

其中$serviceStatePath是上面顯示的XML文件名。那麼我想我可以做這樣的事情:

foreach ($obj in $priorServiceStates.Objects.Object) 
{ 
    if($obj.ServiceState -eq "Running") 
    { 
     $obj.DisplayName; 
    } 
} 

而在這個例子中,我想一個字符串SQL Server (MSSQLSERVER)

回答

31

PowerShell的輸出有內置的XML和XPath的功能。 您可以使用帶有XPath查詢的Select-Xml cmdlet從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'} 
+4

我已經添加了一些解釋。 – mswietlicki

+1

您也可以使用熟悉的屬性語法來導航文檔:'($ xml.Objects.Object |?{$ _。ServiceState -eq「Running」})。DisplayName' – zneak