2

考虑以下 XML 文档:

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

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

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

到现在为止还挺好。但是,如果该元素不存在,则会通过管道传播一个空项:

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

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

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

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

4

2 回答 2

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以这种方式使用,因为它可以节省您调试较大脚本的时间。

于 2012-04-25T23:56:07.270 回答
0

基思是对的,你得到了一个静默错误,它允许空元素沿管道传播。我也是在StrictMode中编写PowerShell脚本的坚定倡导者。

这是我对您的问题的解决方案(将在启用StrictMode的情况下工作)。

如果您对$xml进行快速Get-Member操作,您将看到它的类型为System.Xml.XmlDocument(随后元素的类型为System.Xml.XmlElement)。使用SelectNodes函数,我们可以获得给定XPath的XmlNodeList。所以上面的示例文件可以写成如下:

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

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

*one*
*two*

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

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

正如预期的那样,您不会得到任何响应。

于 2013-08-05T03:58:51.563 回答