How do I select from xml document multiple times with powershell

时间:2015-07-31 20:45:27

标签: xml powershell

I am trying to select multiple groups of elements from an XML document, the sample below shows the type of structure I'm using. Why does the powershell code below only output the 2 names, but not the 2 stores.

[xml]$xml = @'
<root>
  <node>
    <store>HEB</store>
    <name>Fred</name>
  </node>
  <node>
    <store>Fred Meyer</store>
    <name>Barney</name>
  </node>
</root>
'@;

$xml.root.node | select  name -unique

$xml.root.node | select store -unique

Output

.\test.ps1

name
----
Fred
Barney

Desired Output

.\test.ps1

name
----
Fred
Barney

store
-----
HEB
Fred Meyer

1 个答案:

答案 0 :(得分:0)

试试这段代码:

[xml]$xml = @'
<root>
  <node>
    <store>HEB</store>
    <name>Fred</name>
  </node>
  <node>
    <store>Fred Meyer</store>
    <name>Barney</name>
  </node>
</root>
'@;

$xml.root.node | select name  -unique | Out-String

$xml.root.node | select store -unique | Out-String

只有从脚本(.ps1)运行代码时才会出现此问题。当您从提示符运行原始代码时,它可以正常工作。

您遇到的问题是PowerShell如何从脚本返回输出。只要有可能,它将尝试返回完整的对象,而不是最终默认为基础字符串对象。

让我们一步一步:

原始代码:

$xml.root.node | select  name -unique
$xml.root.node | select store -unique

PS C:\> $a = .\Test.ps1
PS C:\> $a

name
----
Fred
Barney



PS C:\> $a | Get-Member


   TypeName: Selected.System.Xml.XmlElement

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
name        NoteProperty System.String name=Fred

请注意,TypeName是一个XmlElement,并且基于成员,有一个NoteProperty&#34; name&#34;。

当我们翻转代码时:

$xml.root.node | select store -unique
$xml.root.node | select  name -unique

PS C:\> $b = .\Test.ps1
PS C:\> $b

store
-----
HEB
Fred Meyer




PS C:\> $b | Get-Member


   TypeName: Selected.System.Xml.XmlElement

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
store       NoteProperty System.String store=HEB

请注意,TypeName是一个XmlElement,并且有一个NoteProperty&#34; store&#34;。

基本上发生的事情是,一旦PowerShell点击第一个命令,它就会设置&#34;输出&#34;变量类型到第一个元素,即名称。当它命中第二个元素时,它会尝试将内容推送到预定义的输出类型中,并且没有任何内容填充它(因为没有名称字段)。您可以通过获取计数来验证这一点:

PS C:\> $a.Count
4

所以有4个元素,但只有前两个元素实际上包含了我们想要的信息。

解决方法是将两个元素都输出为字符串,以便Output类型为字符串,然后返回两个值。

PS C:\> $c = .\Test.ps1
PS C:\> $c

name
----
Fred
Barney




store
-----
HEB
Fred Meyer