【问题标题】:Powershell - Not all XML attributes are getting passed down pipelinePowershell - 并非所有 XML 属性都通过管道传递
【发布时间】:2013-08-13 23:30:52
【问题描述】:

我正在编写一个相当重要的 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

然后我将其通过管道传输到格式表(或 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 搜索中没有找到任何好的线索。

【问题讨论】:

    标签: xml powershell


    【解决方案1】:

    XML 元素肯定是“通过管道传递的”。您正在查看的是format-table 的一个特性:它只查看列表中的第一个对象以确定要打印哪些列。

    这主要是出于性能原因。否则format-table 将不得不迭代列表两次 - 一次确定要输出哪些属性,第二次实际输出它们。此外,列表中的项目通常是统一的。

    在所有其他情况下,“显式优于隐式”的规则适用:

    $stuff.members.member | ft name, rank, serialnumber -AutoSize
    

    【讨论】:

    • 感谢您的快速回复。您是对的,您的解释非常有道理,但它适用于许多命令,例如 export-csv、out-gridview。我只是尝试将它通过管道传输到格式列表,这显然不需要计算要显示的列,并且所有属性都会显示。所以,是的,你是对的,他们都在走出管道。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    • 2016-05-22
    • 2017-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多