首页 > 解决方案 > PowerShell:通过 xpath 解析 xml 节点并创建输出字符串

问题描述

我有以下示例 XML

<AlarmGroup xmlns="http://.." Name="example">
  <TextGroup>
   <TextLayer LanguageId="en">
      <Text ID="1" Value="not used / unknown"/>
      <Text ID="2" Value="not used / unknown"/>
      <Text ID="3" Value="not used / unknown"/>
      <Text ID="4" Value="not used / unknown"/>
    </TextLayer>
    <TextLayer LanguageId="de">  
      <Text ID="1" Value="not used / unknown"/>
      ...   
    </TextLayer> 

' 我尝试遍历每个 Texlayer 并构建一个字符串,如下所示:

zh;1;未使用/未知

en;2;未使用/未知

我尝试了很多方法,例如:

 $AlarmgroupLanguageText = Select-Xml -Xml $Content -XPath "//example:TextLayer" -namespace $ns | select -ExpandProperty node

    $AlarmgroupLanguageText.TextLayer |foreach{
      $AlarmgroupLanguageText |foreach{
        $output += $_.LanguageID + ";" + $_.Text.ID + ";" + $_.Text.Value + "`r`n"

    }   

如果有人可以帮助我提出这个外行的问题,那就太好了。

TIA

标签: xmlpowershell

解决方案


正如@Matthias R. Jessen 在评论中所建议的那样,您的 XPath 有点不稳定。但是,一旦你完成了这项工作,你的代码也会出现其他一些问题,所以退后一步,这里有一种稍微不同的方法:

$xml = [xml] @"
<AlarmGroup xmlns="http://.." Name="example">
  <TextGroup>
   <TextLayer LanguageId="en">
      <Text ID="1" Value="not used / unknown"/>
      <Text ID="2" Value="not used / unknown"/>
      <Text ID="3" Value="not used / unknown"/>
      <Text ID="4" Value="not used / unknown"/>
    </TextLayer>
    <TextLayer LanguageId="de">  
      <Text ID="1" Value="not used / unknown"/>
    </TextLayer>
  </TextGroup>
</AlarmGroup>
"@;

# 1. find a root <AlarmGroup> where Name="example"
$alarmGroup = @( $xml.AlarmGroup | where-object { $_.Name -eq "example" } )[0];

# 2. get all the child <Text> nodes nested under the <AlarmGroup>
$textNodes = @( $alarmGroup.TextGroup.TextLayer.Text );

# 3. format each <Text> node into a string
$textLines = $textNodes | foreach-object {
    $_.ParentNode.LanguageId + ";" + $_.ID + ";" + $_.Value
};

# 4. concatenate all the strings together
$output = $textLines -join "`r`n";

# 5. show the result
$output
# en;1;not used / unknown
# en;2;not used / unknown
# en;3;not used / unknown
# en;4;not used / unknown
# de;1;not used / unknown

棘手的一点是$alarmGroup.TextGroup.TextLayer.Text——它使用成员枚举来扩展TextGroupTextLayer节点以获取所有嵌套Text节点——在这种情况下,它基本上等同于 XPath //TextGroup/TextLayer/Text

其余的希望是不言自明的......


推荐阅读