修改 XML 父属性,使用 powershell 迭代子属性 [英] Modify XML Parent Attributes iterating through Child attributes using powershell

查看:35
本文介绍了修改 XML 父属性,使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆