linux 如何在Powershell REPL控制台中打印xml元素及其属性的列表?

qq24tv8q  于 2023-03-01  发布在  Linux
关注(0)|答案(3)|浏览(103)

参考:
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>
wj8zmpe1

wj8zmpe11#

    • 要解决 * 显示格式 * 问题:**

如果您仔细观察示例输出from your own answer,您会发现,尽管显示内容 * 大多数情况下 * 是有用的,但是author属性的值是author,而不是显示(假定的)first-namelast-name子元素值。
问题是PowerShell的默认输出格式表示具有的子元素:

      • 至少一个 * 属性***
      • 和/或至少一个子元素 * 本身***
    • 仅按元素的 * name *

特别是**对于深度嵌套的元素,这会导致 * 无用的输出 *

    • 解决方法**,可能组合使用:
      • 访问此类元素的.OuterXml.InnerXml属性**,该属性包含元素的完整XML * 文本 *,带有/不带有元素标记本身。
  • 这可能只是在最多另一层嵌套在视觉上有帮助的情况下才有帮助,因为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>
"@

要通过Select-Object和计算属性获得所有<book>元素 (包括<author>子元素的<first-name><last-name〉子元素)的有用表示:

$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获得所有<book>元素的有用表示,请通过一个辅助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>

请注意,您可以将格式化代码 Package 在一个名为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
deyfvvtc

deyfvvtc2#

    • 要解决您的问题**中显示的 * 语法错误 *:
# 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中标识符名称的精确规则*:

更准确地说,PowerShell允许一个标识符不加引号,如果它 * 完全 * 由以下Unicode类别之一的字符组成(在. NET中定义为枚举System.Globalization.UnicodeCategory;圆括号中列出的两个字母的简写可与\p{<shortCategoryName>}一起用于正则表达式中):

  • UppercaseLetterLu
  • LowercaseLetterLl
  • TitlecaseLetterLt
  • ModifierLetterLm
  • OtherLetterLo
  • DecimalDigitNumberNd)-* 第一个 * 字符除外(变量名没有此限制)
  • _("低条",更典型地:"下划线",唯一允许的 * 符号 *)
  • 标识符 * 的类型:
      • 属性名称**(.foo
      • 哈希表文本中的键**(@{ foo = ... }
      • 变量名**($foo
    • 标识符 * 确实 * 支持附加字符,但需要 * 附加语法***:

不遵守上述规则的标识符必须:

    • 属性名 * 和 * 哈希表键 *:带引号的('last-name'"last-name"
    • 变量名 *:包含在{...}${last-name})中

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

  • 除上述内容外,还允许 * 不带引号 * 的以下内容:
  • -("连字符","减号",松散地:"破折号")
  • .("句号"、"句号")
  • 在文件 * 路径 * 中也可以:\)和/

在命令名称中,除了函数和cmdlet名称(您甚至不能用其他字符 * 定义 *)之外,您可以在名称中使用其他字符,只要在调用时将命令名称用引号 * 引起来即可。
然而,这样做是不明智的,因为用户通常期望命令不需要这样的引用;举一个人为的例子:Set-Alias 'a&b' Get-Date; & 'a&b'在技术上是可行的,但是调用的笨拙(引用,然后需要&)使其成为一个糟糕的选择。

ukdjmx9f

ukdjmx9f3#

只是没有使用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>

哎呀。

相关问题