【问题标题】:PowerShell to get attribute values from XML with multiple attributesPowerShell 从具有多个属性的 XML 中获取属性值
【发布时间】:2013-11-15 13:42:36
【问题描述】:

以下 XML 文件是使用 PowerShell 2 从 2008 R2 故障转移集群运行的 Get-ClusterGroup 命令输出的一个对象节点:

<?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>

完整文件还有三个类似的对象节点。其中两个节点在“IsCoreGroup”属性中的值为“False”,另外两个为“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
    }
}

但这对我没有任何帮助。

非常感谢任何帮助!

【问题讨论】:

    标签: xml powershell siblings


    【解决方案1】:

    如果您是属性元素的可变点,则需要访问父节点。由于您需要找到名称为属性值的属性元素,因此我更喜欢使用 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
    

    【讨论】:

    • 太完美了!谢谢!
    • 唯一的缺点是 XPath 查询是区分大小写的,所以如果您有两个与其大小写不一致的文档,XPath 查询将在一个中起作用而在另一个中失败。
    • 确实如此。但是对于计算机生成的文件,情况通常是静态的(至少当文件是新的而不仅仅是更新时)。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-16
    • 2017-08-31
    • 1970-01-01
    • 2012-08-26
    • 1970-01-01
    • 2016-11-05
    相关资源
    最近更新 更多