Powershell,使用 XPath 获取值并转换为逗号分隔的字符串

Powershell to get value using XPath and convert into comma separated string

提问人:Nandan 提问时间:8/17/2023 最后编辑:Nandan 更新时间:8/18/2023 访问量:46

问:

<data>
    <ValueSet Version="6.6">
        <entry key="ORGID">
            <Value>852357951364</Value>
        </entry>
        <entry key="MESSAGE_CODE">
            <Value>MESSAGE1</Value>
        </entry>
        <entry key="REVERSAL">
            <Value>REVERSAL1</Value>
        </entry>
    </ValueSet>
    <ValueSet Version="6.6">
        <entry key="ORGID">
            <Value>852357951365</Value>
        </entry>
        <entry key="MESSAGE_CODE">
            <Value>MESSAGE2</Value>
        </entry>
        <entry key="REVERSAL">
            <Value>REVERSAL2</Value>
        </entry>
    </ValueSet>
</data>

我使用下面的 Powershell 脚本从上面的 XML 中单独获取了 ORGID 值

$XMLfile = 'C:\Users\XML_Input.xml'
Select-Xml -Path $XMLfile -XPath '//entry[@key="ORGID"]' | foreach {$_.node.Value}

.

执行上述 PowerShell 脚本后,ORGID 将逐个打印,如下所示 .852357951364

852357951365

我想用逗号分隔的单行值打印 ORGID,而不是一一打印 ORGID ,例如 852357951364,852357951365

请帮我形成一个单行字符串的输出

xml powershell xpath 命令行 xml 解析

评论

1赞 Daniel 8/17/2023
使用运算符-join(Select-Xml -Path $XMLfile -XPath '//entry[@key="ORGID"]' | foreach {$_.node.Value}) -join ","

答:

0赞 jdweng 8/17/2023 #1

使用 Powershell

using assembly System.Xml.Linq

$inputFilename = "c:\temp\test.xml"
$outputFilename = "c:\temp\test.csv"

$doc = [System.Xml.Linq.XDocument]::Load($inputFilename)
$valueSets = $doc.Descendants("ValueSet")

$table = [System.Collections.ArrayList]::new()
foreach($valueSet in $valueSets)
{
   foreach($entry in $valueset.Elements())
   {
      $key = $entry.Attribute('key').Value
      $value = $entry.Descendants('Value')[0].Value

      switch($key)
      {
         'ORGID' {$orgid = $value}
         'MESSAGE_CODE' {$messageCode = $value}
         'REVERSAL' {$reversal = $value}
      }
   }
   $newRow = [pscustomobject]@{
         ORGID=$orgid
         MESSAGE_CODE=$messageCode
         REVERSAL=$reversal
   }
   $table.Add($newRow) | Out-Null
}
$table | Format-Table
$table | Export-CSV -Path $outputFilename -NoTypeInformation

结果

"ORGID","MESSAGE_CODE","REVERSAL"
"852357951364","MESSAGE1","REVERSAL1"
"852357951365","MESSAGE2","REVERSAL2"
1赞 mklement0 8/18/2023 #2

您的问题并非特定于 XML 解析。它可以简化为:

  • 给定输出可变数量的对象的 PowerShell 管道,如何使用分隔符将这些对象(作为字符串)联接以形成单个字符串?

您有两种选择:

适用于您的案例:

# -join operator
(Select-Xml -Path $XMLfile -XPath '//entry[@key="ORGID"]').Node.Value -join ','

# PS v7+: Join-String cmdlet.
(Select-Xml -Path $XMLfile -XPath '//entry[@key="ORGID"]').Node |
  Join-String -Property Value -Separator ','

注意:

  • 这两个命令都利用了成员访问枚举,这允许你直接访问数组上的属性(类似列表的数据类型),并让 PowerShell 自动将其应用于每个元素,将结果作为值数组返回(假设有两个或更多)。

  • 使用 时,应用了两个级别的成员访问枚举 (),因此没有必要使用 。-join.Node.Valueforeach {$_.node.Value}

  • 使用 ,我只使用了一个级别 (),以展示 通过 接受目标属性名称的能力。Join-String.NodeJoin-String-Property

    • 但是,请注意,不使用成员访问枚举和尝试是不通的,因为这样就会被解释为面上名为 ;同样的警告适用于具有参数(如 Select-Object)的所有 cmdlet。-Property Node.ValueNode.ValueNode.Value-Property