考虑以下XML文档:
$xml = [xml] "<root><value>one</value><value>two</value></root>"
然后打印值(带有一些前缀/后缀):
$xml.root.value | %{"*$_*"}
*one*
*two*
到目前为止一切顺利。但是,如果元素不存在,则通过管道传播空项:
$xml.root.foo | %{"*$_*"}
**
为什么?有没有办法避免这种额外的检查:
$xml.root.foo | ?{$_} | %{"*$_*"}
很容易忘记,而且似乎容易出错。
答案 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'+ "*"}
你没有得到任何回应,正如预料的那样。