Powershell 4 XML节点访问符号拼图

时间:2017-02-23 14:02:21

标签: xml powershell

Powershell 4 Windows Server 2008 R2

所以最近我写了一个Powershell脚本来拨入我的机器网页配置文件的应用程序池中。我真的不知道访问XML节点的方式的名称,但这是第一次完成它的方式:

$appPoolNode = ($config['configuration']['system.applicationHost']['applicationPools']['add'] | where {$_.name -eq $AppPoolName})

可悲的是,除了默认的应用程序池之外,这不起作用 因此,如果我想为另一个应用程序池更改某些内容,我无法从上面的代码行返回任何内容。我找到了一位同事,他向我展示了访问XML节点的点符号:

$appPoolNode = ($config.configuration.'system.applicationHost'.applicationPools.add | where {$_.name -eq $AppPoolName})

不知何故,这段代码有效。

我的问题是:
什么样的XML访问是第一个被调用的代码示例代码,为什么点符号适用于其他应用程序池而不仅仅是defaultappPool,就像第一个代码示例一样?

1 个答案:

答案 0 :(得分:4)

使用PowerShell魔术的乐趣: - )

您的$config变量属于System.Xml.XmlNode派生的某种类型。当您将一些字符串强制转换为[xml]时,PowerShell会执行此操作。

此类型包括属性Item,其中C#中的属性用于处理带括号的访问器语法,因此编写

$config['a']

被解析为函数调用

$config.Item('a')

返回单个值 - 与给定名称匹配的第一个子节点。

现在,如果对此使用.表示法,则只需调用另一个属性,但在这种情况下,PowerShell在解析XML文件时会动态添加一个属性。

它为每个子节点名称及其在当前节点上找到的每个属性添加一个属性。如果有多个具有给定名称的子节点,则会使该属性返回这些节点的数组,并且它与Item方法不同,后者仅返回第一个值。

要通过一个简单的例子来看这个,请考虑

$x = [xml]"<a> <b Id='1'/> <b Id='2'/> </a>"

然后$x | Get-Member显示通常的XmlDocument属性,包括Item,以及返回单个XmlElement的属性a。所以在这一点上

$x['a']
$x.Item('a')
$x.a

所有返回相同。现在做$x.a | Get-Member。您看到Item仍返回单个XmlElement,但由于b在XML中出现多次,因此PowerShell允许b属性返回一个通用对象数组(恰好是XmlElement类型)

因此

$x.a.b

为您提供Id个值,而

 $x.a['b']

只返回第一个。