此XML管道中的null项是什么?

时间:2012-04-25 22:38:10

标签: powershell

考虑以下XML文档:

$xml = [xml] "<root><value>one</value><value>two</value></root>"

然后打印值(带有一些前缀/后缀):

$xml.root.value | %{"*$_*"}
*one*
*two*

到目前为止一切顺利。但是,如果元素不存在,则通过管道传播空项:

$xml.root.foo | %{"*$_*"}
**

为什么?有没有办法避免这种额外的检查:

$xml.root.foo | ?{$_} | %{"*$_*"}

很容易忘记,而且似乎容易出错。

2 个答案:

答案 0 :(得分:2)

要关闭缺失属性的静默失败,请使用Set-StrictMode -Version Latest,例如:

PS> $xml = [xml] "<root><value>one</value><value>two</value></root>"
PS> $xml.root.foo | %{"*$_*"}
**
PS> Set-StrictMode -Version Latest
PS> $xml.root.foo | %{"*$_*"}
Property 'foo' cannot be found on this object. Make sure that it exists.
At line:1 char:1
+ $xml.root.foo | %{"*$_*"}
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], PropertyNotFoundException
    + FullyQualifiedErrorId : PropertyNotFoundStrict

请注意,这也会捕获对不存在的变量的引用。我强烈建议以这种方式使用Set-StrictMode,因为它可以节省大型脚本的调试时间。

答案 1 :(得分:0)

Keith是正确的,你得到一个无声错误,它允许null元素沿管道传播。我也是 PowerShell 脚本的强烈支持者。

以下是我的问题解决方案(可以使用 StrictMode 启用)。

如果您在 $ xml 上快速 Get-Member ,您会看到它的类型为{ {3}}(随后元素的类型为 System.Xml.XmlElement )。使用 SelectNodes 功能,我们可以为给定的 XPath获取 XmlNodeList 即可。所以上面的示例文件可以写成如下:

$xml.SelectNodes("//root/value")  | % {"*" + $_.'#text'+ "*"}

这将为您提供所需的输出。

*one*
*two*

如果我们开始寻找不存在的节点:

$xml.SelectNodes("//root/value")  | % {"*" + $_.'#text'+ "*"}

你没有得到任何回应,正如预料的那样。