【问题标题】:Grab all value between 2 XML tags获取 2 个 XML 标记之间的所有值
【发布时间】:2018-02-07 08:11:49
【问题描述】:

在 PowerShell 中,我试图根据类别属性检索 2 个 XML 标记之间的所有字符串值。

示例代码展示:

<Report name="test" category="thisone">
  <String>test</String>
  <String>test2</String>
  <Report name="new test" category="hi">
    <String>hello</String>
    <String>hi again</String>
  </Report>
</Report>

所以我想输出这 4 个字符串,基于类别为“thisone”的 &lt;Report&gt; 标签。我遇到了麻烦,因为两个 XML 标记都以“Report”开头,但类别“hi”是“thisone”的子项,所以我也需要它的字符串。

【问题讨论】:

    标签: xml powershell scripting


    【解决方案1】:

    您可以通过管道将您的 XML 传递给 Select-Xml,然后像这样对它进行 XPath 搜索:

    $text = Get-Content C:\Path\To\File.xml
    $text | Select-Xml -XPath '//Report[@category="thisone"]//String'|%{$_.Node.'#text'}
    

    重要的部分是 XPath 搜索。 // 表示从 XML 的根开始的所有内容,然后查找具有 category 属性和值为 "thisone"Report 节点。然后它会查看过去的所有节点(同样由// 表示)以查找String 节点。它将所有这些string 节点传递给ForEach-Object 循环(使用别名%),并为每个节点扩展Node 属性和其中的#text 属性。这导致:

    test
    test2
    hello
    hi again
    

    要将这些字符串输出到文件,您可以通过管道将第二行发送到 Set-Content(或 Out-File,但该 cmdlet 有点过时 IMO)。

    $text | Select-Xml -XPath '//Report[@category="thisone"]//String'|%{$_.Node.'#text'} | Set-Content C:\Path\To\NewFile.txt
    

    或者要同时输出到屏幕和文件,您可以使用Tee-Object,例如:

    $text | Select-Xml -XPath '//Report[@category="thisone"]//String'|%{$_.Node.'#text'} | Tee-Object -FilePath C:\Path\To\NewFile.txt
    

    【讨论】:

    • 看起来有效!我使用了 Out-File,它也很有效。我没有意识到的是,它结合了所有字符串值(所有类别都带有'thisone')。有没有办法可以将它们作为变量存储在数组中以区分彼此?这将允许我对每次出现的事件进行 Out-File...
    • 好吧,当然,如果您将输出重定向到文件,那么它不会显示任何内容。这就是那里的目的。如果你想输出到一个文件以及显示你可以使用Tee-Object
    • 我编辑了我的评论,因为我之前有一个错字。我现在将它输出到一个文件中,但是我无法将第一次出现的“thisone”与第二次分开,因为它将所有内容都倾倒在一个文件中。我正在考虑将它们作为变量存储在数组中......
    • 我刚刚注意到它没有返回我的 。我有一些空的 将它们分隔在输出中......我相信它与这部分有关:|%{$_.Node.'#text'} 我可以修改它以包含文本和那些空的那些?谢谢
    • 不,这只是扩展实际包含文本字符串的属性。您的空字符串是否嵌套在“thisone”类别下?您能否用更准确的示例更新问题以进行测试?
    猜你喜欢
    • 2011-09-25
    • 2012-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-04
    • 2016-08-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多