使用 powershell 修改通过子属性迭代的 XML 父属性 [英] Modify XML Parent Attributes iterating through Child attributes using powershell
问题描述
所以我有以下 xml (items.xml),我想找到子节点项的属性,遍历属性,如果我在父节点级别找到类似的属性,用子节点属性替换相同的属性并删除名称以外的子属性.
So I have the following xml (items.xml) and I want to find the attributes of the child node item iterate through the attributes and if I find similar attributes at parent node level replace the same with the child node attributes and remove the child attributes other than the name.
<items>
<model type="model1" name="default" price="12.12" date="some_value">
<PriceData>
<item name="watch" price="24.28" date="2013-12-01" />
</PriceData>
</model>
<model type="model2" name="default" price="12.12" date="some_value">
<PriceData>
<item name="toy" price="22.34" date="2013-12-02"/>
</PriceData>
</model>
<model type="model3" name="default" price="12.12" date="some_value">
<PriceData>
<item name="bread" price="24.12" date="2013-12-03"/>
</PriceData>
</model>
</items>
最终的 xml 应该是这样的
The final xml should look like this
<items>
<model type="model1" name="watch" price="24.28" date="2013-12-0">
<PriceData>
<item name="watch" />
</PriceData>
</model>
<model type="model2" name="toy" price="22.34" date="2013-12-02">
<PriceData>
<item name="toy" "/>
</PriceData>
</model>
<model type="model3" name="bread" price="24.12" date="2013-12-03">
<PriceData>
<item name="bread" />
</PriceData>
</model>
</items>
我能够获取子级的属性,但我无法从子级遍历回父节点.
I'm able to get the attributes at child level, but I'm unable to traverse back to the parent node from the child level.
以下是我试图到达父节点的代码
Following is the code that I tried to get to the parent nodes
[xml]$model = get-content items.xml
$model.SelectNodes("//item/@*")
Output:
#text
-----
watch
24.28
2013-12-01
toy
22.34
2013-12-02
bread
24.12
2013-12-03
$model.SelectNodes("//item/@*") | foreach {write-host $_.parentnode}
No Output:
$model.SelectNodes("//item/@*") | foreach {write-host $_.parentnode.parentnode}
No Output:
我可以得到子节点的属性名如下:
I can get the attribute names of the child node as follows:
$model.SelectNodes("//item/@*") | foreach {write-host $_.name}
Output:
PS C:BIOS_Work_DirKit_Manifest_test> $model.SelectNodes("//item/@*") | foreach {write-host $_.name}
name
price
date
name
price
date
name
price
date
现在对于每个属性,我只需要回到父节点,检查是否存在类似的属性并将其替换为子节点属性
Now for each attribute, I just need to go back to the parent node, check if similar attribute exists and replace it with the child node attribute
所以,我正在寻找类似的东西
So, I'm looking for something like
$model.SelectNodes("//item/@*") | foreach {($_.name).parentnode.parentnode.($_.name)} | <some code to replace parentnode attribute with child attribute>
然后删除子属性类似
$model.SelectNodes("//item/@*") | where {$_.name -notlike "name"} | foreach {$_.Removeattribute()}
如果这两个都可以在一个命令中完成,那就太棒了
and if both these can be done in one single command that would be awesome
也许我也在尝试在一行中做很多事情
Maybe I'm also trying to do a lot of things in a single line
非常感谢任何指针!不太确定我在这里做错了什么,因为 powershell 不会为父节点的使用抛出错误,但不会打印任何内容.所有经验丰富的程序员的任何帮助都令人惊叹!
Any pointers are greatly appreciated! Not really sure what am I doing wrong here as powershell does not throw an error for parent node usage but just does not print anything. Any help is amazing from all you experienced programmers!!
推荐答案
您可以通过 OwnerElement
属性.所以这是获得所需输出的一种可能方法:
You can get parent element from an attribute via OwnerElement
property. So this is one possible way to get the desired output :
$model.SelectNodes("//item/@*") |
ForEach {
# set attributes value on `model` element
$_.OwnerElement.ParentNode.ParentNode.SetAttribute($_.LocalName, $_.Value)
# remove attributes except `name` from `item` element
If ($_.LocalName -ne "name") { $_.OwnerElement.RemoveAttribute($_.LocalName) }
}
这篇关于使用 powershell 修改通过子属性迭代的 XML 父属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!