【问题标题】:How to print a list of xml elements and their properties in the Powershell REPL console?如何在 Powershell REPL 控制台中打印 xml 元素及其属性的列表?
【发布时间】:2021-03-23 15:54:27
【问题描述】:

参考:

https://www.red-gate.com/simple-talk/sysadmin/powershell/powershell-data-basics-xml/

和:

https://stackoverflow.com/a/65264118/4531180

如何打印元素列表及其属性?

PS /home/nicholas/powershell> 
PS /home/nicholas/powershell> $doc = new-object System.Xml.XmlDocument
PS /home/nicholas/powershell> $file = resolve-path('./bookstore.xml') 
PS /home/nicholas/powershell> $doc.load($file)                                           
PS /home/nicholas/powershell> 
PS /home/nicholas/powershell> $doc.bookstore.book[1].author.first-name
ParserError: 
Line |
   1 |  $doc.bookstore.book[1].author.first-name
     |                                     ~~~~~
     | Unexpected token '-name' in expression or statement.

PS /home/nicholas/powershell> 
PS /home/nicholas/powershell> $doc.bookstore.book[1].author           

first-name last-name
---------- ---------
Margaret   Atwood

PS /home/nicholas/powershell> 
PS /home/nicholas/powershell> $doc.bookstore

bk          book
--          ----
urn:samples {book, book, book, book}

PS /home/nicholas/powershell> 

【问题讨论】:

  • 小心你的引用,我建议你避开聪明的,(curly),引号,“./bookstore.xml”,并使用愚蠢的,(直),改为引号,"/bookstore/book[2]".
  • 哦,这是从另一个网站复制粘贴的。没看到,谢谢但是,文件加载正常不是问题。
  • 我敢打赌,论坛软件并没有只更改一对直引号,而其他所有引号都保持不变。如果您确实复制/粘贴了它们,那么您已经使用了它们,(唯一的另一种选择是您稍后编辑粘贴的信息,并在这样做时自己介绍了它们)。我看到您现在已经在上面编辑了您的评论!以及完全改变你的代码和输出!
  • 它实际上是该网站的复制粘贴,我只是省略了在点运算符中指定“书”。但感谢您查看。我明白你的意思。
  • @Compo:虽然通常建议避免使用非 ASCII 引号字符,但请注意 PowerShell 也很乐意接受所谓的印刷引号字符 - 唯一需要注意的是您的源代码文件必须正确编码(在 Windows PowerShell 中表示 带有 BOM 的 Unicode 编码) - 请参阅 this answer.

标签: linux xml powershell xpath read-eval-print-loop


【解决方案1】:

只是没有使用books

PS /home/nicholas/powershell> 
PS /home/nicholas/powershell> $doc.bookstore.book

genre           : novel
publicationdate : 1997
ISBN            : 1-861001-57-8
title           : Pride And Prejudice
author          : author
price           : 24.95

genre           : novel
publicationdate : 1992
ISBN            : 1-861002-30-1
title           : The Handmaid's Tale
author          : author
price           : 29.95

genre           : novel
publicationdate : 1991
ISBN            : 1-861001-57-6
title           : Emma
author          : author
price           : 19.95

genre           : novel
publicationdate : 1982
ISBN            : 1-861001-45-3
title           : Sense and Sensibility
author          : author
price           : 19.95


PS /home/nicholas/powershell> 

哎呀。

【讨论】:

    【解决方案2】:

    解决问题中显示的语法错误

    # BROKEN: `first-name` cannot be used without quoting
    $doc.bookstore.book[1].author.first-name
    
    # OK:
    $doc.bookstore.book[1].author.'first-name'
    

    元素名称 first-name,在 PowerShell 中显示为 属性名称,不能不带引号使用,因为 - 会被解释为 减法运算符,导致你看到的错误。

    简而言之:

    • 只有字母、数字和_(下划线)可以用于不带引号的属性名称;未引用的变量名同上。[1]

    • 如有疑问,引用


    [1] PowerShell 中标识符名称的确切规则

    更准确地说,如果标识符由以下 Unicode 类别之一的字符组成,PowerShell 允许不加引号(在 .NET 中定义为枚举 @987654321 @;括号中的two-letter shorthands可以和正则表达式中的\p{<shortCategoryName>}一起使用):

    标识符的类型

    • 属性名称 (.foo)
    • 散列表文字中的键 (@{ foo = ... })
    • 变量名 ($foo)

    标识符确实支持额外的字符,但需要额外的语法

    不符合上述规则的标识符必须是:

    • 属性名称哈希表键:引用('last-name'"last-name"
    • 变量名:括在{...} (${last-name})中

    请注意,扩展规则适用于命令名(函数名、cmdlet、脚本或可执行文件及其别名)模块姓名

    • 除上述内容外,还允许以下内容不加引号
      • -(“连字符”,“减号”,松散地:“破折号”)
      • .(“句号”、“句号”)
      • 在文件 paths 中还有:\) 和 /)

    在命令名称中,除了函数和 cmdlet 名称(您甚至无法用其他字符定义)之外,您可以在名称中使用其他字符,只要您 引用调用时的命令名称。

    但是,这样做是不明智的,因为用户通常希望命令不需要这样的引用;举一个人为的例子:Set-Alias 'a&b' Get-Date; & 'a&b' 在技术上是可行的,但是调用的笨拙(引用,然后需要&)使得这是一个糟糕的选择。

    【讨论】:

      【解决方案3】:

      解决显示格式问题

      如果您仔细查看示例输出 from your own answer,您会发现即使显示大部分很有帮助,author 属性的值是 author,而不是显示(假定的)first-namelast-name 子元素值。

      问题在于 PowerShell 的默认输出格式表示具有的子元素:

      • 至少一个属性
      • 和/或至少一个子元素本身

      仅按元素的名称

      尤其是深度嵌套的元素,这会导致无用的输出

      解决方法,可能结合使用:

      • 访问此类元素的.OuterXml.InnerXml 属性,其中包含元素的完整XML文本,带有/不带有元素的标签。 p>

        • 这可能只会有帮助,也许最多另一层嵌套会在视觉上有所帮助,因为 XML 文本是 单行 表示,不是印刷精美。

        • 您可以.OuterXml / InnerXml 值传递给漂亮的打印函数,这需要一些额外的工作,但是,因为 PowerShell 没有直接公开此类功能。

      • Select-Object(或者,仅出于显示目的,使用 Format-* cmdlet,例如 Format-Table)与 calculated properties 一起使用。

        • 虽然这可以让您完全控制显示的内容,但工作量更大。

      请参阅下面的示例。


      # Sample XML document
      $xmlDoc = [xml] @"
      <?xml version="1.0"?>
      <bookstore>
         <book id="bk101">
            <author>
              <first-name>Matthew</first-name>
              <last-name>Gambardella</last-name>
            </author>
            <title>XML Developer's Guide</title>
            <genre>Computer</genre>
            <price>44.95</price>
            <publish_date>2000-10-01</publish_date>
            <description>An in-depth look at creating applications with XML.</description>
         </book>
         <book id="bk102">
            <author>
              <first-name>Kim</first-name>
              <last-name>Rall</last-name>
            </author>
            <title>Midnight Rain</title>
            <genre>Fantasy</genre>
            <price>5.95</price>
            <publish_date>2000-12-16</publish_date>
            <description>A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.</description>
         </book>
      </bookstore>
      "@
      

      为了获得所有&lt;book&gt; 元素的有用表示包括&lt;author&gt; 子元素的&lt;first-name&gt;&lt;last-name> 子元素 通过Select-Object 和计算属性

      $xmldoc.bookstore.book | Select-Object id, 
         @{ n='author'; e={ $_.author.'first-name' + ' ' + $_.author.'last-name'} }, 
         title, genre, price, publish_date, description
      

      这会产生(注意author 属性现在如何列出名字和姓氏):

      id           : bk101
      author       : Matthew Gambardella
      title        : XML Developer's Guide
      genre        : Computer
      price        : 44.95
      publish_date : 2000-10-01
      description  : An in-depth look at creating applications with XML.
      
      id           : bk102
      author       : Kim Rall
      title        : Midnight Rain
      genre        : Fantasy
      price        : 5.95
      publish_date : 2000-12-16
      description  : A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.
      

      要通过漂亮的 XML 获得所有 &lt;book&gt; 元素的有用表示,通过辅助 System.Xml.Linq.XDocument 实例:

      # Load the assembly that contains XDocument.
      # Note: Required in Windows PowerShell only, and only once per session.
      Add-Type -AssemblyName System.Xml.Linq
      
      $xmldoc.bookstore.book | ForEach-Object {
        ([System.Xml.Linq.XDocument] $_.OuterXml).ToString()
      }
      

      这会产生(漂亮的 XML 表示):

      <book id="bk101">
        <author>
          <first-name>Matthew</first-name>
          <last-name>Gambardella</last-name>
        </author>
        <title>XML Developer's Guide</title>
        <genre>Computer</genre>
        <price>44.95</price>
        <publish_date>2000-10-01</publish_date>
        <description>An in-depth look at creating applications with XML.</description>
      </book>
      <book id="bk102">
        <author>
          <first-name>Kim</first-name>
          <last-name>Rall</last-name>
        </author>
        <title>Midnight Rain</title>
        <genre>Fantasy</genre>
        <price>5.95</price>
        <publish_date>2000-12-16</publish_date>
        <description>A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.</description>
      </book>
      

      请注意,您可以将格式化代码包装在一个名为 Format-Xml 的简单(过滤器)函数中,您可以将其放入您的 $PROFILE 文件中(在 Windows PowerShell 中,也可以将 Add-Type -AssemblyName System.Xml.Linq那里,在它上面):

      filter Format-Xml { ([System.Xml.Linq.XDocument] $_.OuterXml).ToString() }
      

      现在格式化很简单:

      $xmldoc.bookstore.book | Format-Xml
      

      【讨论】:

        猜你喜欢
        • 2021-03-17
        • 2016-03-30
        • 2015-01-26
        • 1970-01-01
        • 2021-04-18
        • 1970-01-01
        • 1970-01-01
        • 2022-01-25
        • 1970-01-01
        相关资源
        最近更新 更多