使用 Powershell 解析不一致的 XML-objects

Parsing non-consistent XML-objects using Powershell

我正在尝试解析不包含统一属性的 XML。例子

<root>
<object>
  <name>Object1</name>
  <valueString>string</valueString>
</object>
<object>
  <name>Object2</name>
  <valueBoolean>true</valueBoolean>
</object>
</root>

子属性的数量始终相同,但有时是布尔值,有时是字符串,标签名称也会相应变化。问题不在于类型本身,而是使用 Powershell,我必须事先知道标签名称才能获得附加到它的值。

目前我正在做这样的事情:

foreach($item in $items){
  if(!$item.object.valueString){
     $temp = $item.object.valueBoolean
  }
  else{
     $temp = $item.object.valueString
  }
  $properties = @{
      Name = $item.object.Name
      value = $temp
  }
}

这行得通,但我想要一个更优雅的解决方案 + 目前它非常严格,你必须迎合每一种可能性。

有没有更好的方法?

干杯

这不一定能解决奇怪的 XML 垃圾的一般问题,但合并不同可能性的辅助函数可能会使事情 trim 更重要。已测试:

function value ($parent) {
    :args foreach ($name in $args) {
        $v = $parent.$("value$name")
        if ($v -ne $null) {$v; break args}
    }
}

您可以像 value ($item.object) Boolean String 一样使用它,假设所有这些节点都具有相同的 valueXXX 模式。 (如果它们总是来自一个固定的集合,您可以通过硬编码而不是 $args 来 trim 进一步降低使用率。如果变化比 valueXXX 多得多,您将需要相应地调整辅助函数。)

解释:使用 $args 获取所有未命名的参数,然后循环遍历,从字符串插值动态构建 属性 访问器,并找到第一个非空结果,这然后 returns。循环被标记只是为了确定。

您可以使用 ChildNodes 属性 按顺序访问子元素:

$xml=[xml]@'
<root>
  <object>
    <name>Object1</name>
    <valueString>string</valueString>
  </object>
  <object>
    <name>Object2</name>
    <valueBoolean>true</valueBoolean>
  </object>
</root>
'@
foreach($object in $xml.root.object){
    $value=$object.ChildNodes[1]
    [PSCustomObject]@{
        Name=$object.Name
        ValueName=$value.Name
        Value=$value.'#text'
    }
}