修改 XML 父属性,使用 powershell 迭代子属性 [英] 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_Dir\Kit_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) }
}
这篇关于修改 XML 父属性,使用 powershell 迭代子属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!