我正在编写一个相当实质的Posh模块作为一组RESTful Web服务的CLI前端。我有一个奇怪的问题,我能够表征,但没有找到一个干净的解决方案。
我并不总是知道期望什么属性,并且一些节点可能具有某个属性,其他节点可能没有该属性。我的问题有时(经常阅读)如果一个属性不存在于所有节点中,它将不会传递给任何节点的管道。它似乎与XML中第一个节点中的属性有关。
对于一个非常简单的示例,请考虑这是XML文件example.xml的内容:
<members>
<member>
<name>Joe</name>
<rank>Grand Poobah</rank>
<serialnumber>1234</serialnumber>
</member>
<member>
<name>Fred</name>
<serialnumber>1234</serialnumber>
</member>
</members>
我导入它并将其分配给xml已转换变量:
[xml]$stuff = Get-Content .\example.xml
然后我将它传输到format-table(或out-gridview,export-csv等)
$stuff.members.member | ft -AutoSize
name rank serialnumber
---- ---- ------------
Joe Grand Poobah 1234
Fred 1234
效果很好。
现在,如果FIRST节点没有rank属性:
<members>
<member>
<name>Fred</name>
<serialnumber>1234</serialnumber>
</member>
<member>
<name>Joe</name>
<rank>Grand Poobah</rank>
<serialnumber>1234</serialnumber>
</member>
</members>
现在,当我执行相同的导入并将其传递给管道时,“rank”属性不会传递给管道。
$stuff.members.member | ft -AutoSize
name serialnumber
---- ------------
Fred 1234
Joe 1234
我可以通过明确命名属性来强制它:
$stuff.members.member | select-object -Property name, rank, serialnumber | ft
name rank serialnumber
---- ---- ------------
Fred 1234
Joe Grand Poobah 1234
明确命名属性是错误的一个方法,因为可以在没有警告的情况下添加属性。我想尽可能保持代码灵活处理新属性。
我以为我可以使用“select-object -property *”但是这会添加很多我不想要的PowerShell插入的XML内容,并且仍然没有管道rank属性。
$stuff.members.member | select-object -Property *| ft -AutoSize
name serialnumber LocalName NamespaceURI Prefix NodeType ParentNode OwnerDocument IsEmpty Attributes
---- ------------ --------- ------------ ------ -------- ---------- ------------- ------- ----------
Fred 1234 member Element members #document False {}
Joe 1234 member Element members #document False {}
有谁熟悉处理这种情况的任何好方法?我没有在Google搜索上找到任何好的线索。
答案 0 :(得分:5)
XML元素肯定是“传递给管道”。你正在看的是format-table
的特性:它只查看列表中的第一个对象来确定要打印的列。
这主要是出于性能原因。否则format-table
必须迭代列表两次 - 一次找出要输出的属性,第二次实际输出它们。另外,列表中的项目通常都是统一的。
在所有其他情况下,“明确胜于隐性”的规则适用:
$stuff.members.member | ft name, rank, serialnumber -AutoSize