web-dev-qa-db-ja.com

複数の属性を持つXMLから属性値を取得するPowerShell

次のXMLファイルは、PowerShell2を使用して2008R2フェールオーバークラスターから実行されるコマンドGet-ClusterGroupからの出力の1つのオブジェクトノードです。

<?xml version="1.0"?>
<Objects>
  <Object>
    <Property Name="Cluster">Cluster1</Property>
    <Property Name="IsCoreGroup">False</Property>
    <Property Name="OwnerNode">Node1</Property>
    <Property Name="State">Offline</Property>
    <Property Name="Name">SAP PL1</Property>
    <Property Name="Description" />
    <Property Name="PersistentState">1</Property>
    <Property Name="FailoverThreshold">4294967295</Property>
    <Property Name="FailoverPeriod">6</Property>
    <Property Name="AutoFailbackType">1</Property>
    <Property Name="FailbackWindowStart">4294967295</Property>
    <Property Name="FailbackWindowEnd">4294967295</Property>
    <Property Name="Priority">1</Property>
    <Property Name="DefaultOwner">4294967295</Property>
    <Property Name="AntiAffinityClassNames" />
    <Property Name="Id">a5ff557f-c81a-43aa-bdb9-e09d0a1103df</Property>
  </Object>
</Objects>

完全なファイルには、これに似たオブジェクトノードがさらに3つあります。これらのノードのうち2つは、「IsCoreGroup」属性に「False」という値があり、他の2つは「True」です。私がやろうとしているのは、「IsCoreGroup」属性に「False」の値を持つオブジェクトノードから「Name」プロパティの値とその他の属性を取得することです。

この属性を取得する方法をいくつか試しましたが、兄弟属性にドリルダウンする方法がわかりません。

これが私がこれまでに持っているものです:

[xml]$file = get-content C:\Admin\ClusterGroups.xml
$xmlProperties = $file.SelectNodes("/Objects/Object/Property")
Foreach ($xmlProperty in $xmlProperties) {
    $strName = ($xmlProperty | Where-Object {$_.Name -eq "IsCoreGroup" }).InnerXml
    If ($strName -eq "False")
    {
    Echo $xmlProperty
    }
}

これは私に次のことを与えます:

Name                                      #text                                    
----                                      -----                                    
IsCoreGroup                               False      

しかし、兄弟のプロパティを取得する方法がわかりません

次の方法でレベルをバックアップしてみました。

[xml]$file = get-content C:\Admin\ClusterGroups.xml
$xmlObjects = $file.SelectNodes("/Objects/Object")
Foreach ($xmlObject in $xmlObjects) {
    $strCoreGroup = ($xmlObject | Where-Object {$_.Property.Name -eq "IsCoreGroup" }).InnerXml
    If ($strCoreGroup -eq "False")
    {
    Echo $xmlObject
    }
}

しかし、それは私をどこにも連れて行かない。

どんな助けでも大歓迎です!

6
user888818

変数がproperty-elementを指している場合は、親ノードにアクセスする必要があります。名前が属性値であるプロパティ要素を見つける必要があるため、xpathを使用してこれを行うことをお勧めします。

$xmlProperties = $file.SelectNodes("/Objects/Object/Property")
Foreach ($xmlProperty in $xmlProperties) {
    $strName = ($xmlProperty | Where-Object {$_.Name -eq "IsCoreGroup" }).InnerXml
    If ($strName -eq "False")
    {
        # .. means parent node. So the xpath goes up one level from property, and searches for the new property you want.
        $xmlProperty.SelectSingleNode('../Property[@Name="Name"]').InnerXml
    }
}

$xmlproperty.parentnode.whateveryouwantを実行することもできます。

個人的には、xpathを使用して適切なオブジェクトを最初に検索し、オブジェクトレベルで取得するので、レベルを上げることなく、オブジェクトノードの他のプロパティに簡単にアクセスできます。

$file.SelectNodes('/Objects/Object[Property[@Name="IsCoreGroup"]="False"]') | % { 
    #Foreach object with IsCoreGroup = false, get value of property with Cluster1 as Name attribute
    $_.SelectSingleNode('Property[@Name="Cluster"]').innerxml
}

Cluster1
5
Frode F.