我试图解析一个不包含统一属性的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
}
}
这有效,但我想要一个更优雅的解决方案+目前它很僵硬,你必须满足每一种可能性。
有更好的方法吗?
干杯
答案 0 :(得分:2)
您可以使用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'
}
}
答案 1 :(得分:1)
这并不一定能解决奇怪的XML垃圾的一般问题,但是合并不同可能性的辅助函数可能会使事情变得微不足道。测试:
function value ($parent) {
:args foreach ($name in $args) {
$v = $parent.$("value$name")
if ($v -ne $null) {$v; break args}
}
}
假设所有节点都具有相同的valueXXX模式,您就像value ($item.object) Boolean String
一样使用它。 (如果他们总是来自一个固定的设置,你可以通过硬编码而不是$args
来进一步减少使用量。如果有更多的变化而不是valueXXX,你&#39 ; ll需要相应地调整辅助函数。)
说明:使用$args
获取所有未命名的参数,然后循环,从字符串插值中动态构建属性访问器,并找到第一个非空结果,然后返回。循环被标记为确定。