使用powershell修改迭代子属性的XML父属性

使用powershell修改迭代子属性的XML父属性,xml,powershell,xml-parsing,Xml,Powershell,Xml Parsing,因此,我有以下xml(items.xml),我想找到子节点项的属性,并在属性中迭代,如果在父节点级别找到类似的属性,则将其替换为子节点属性,并删除除名称以外的子属性 <items> <model type="model1" name="default" price="12.12" date="some_value"> <PriceData> <item name="watch" price="24.28"

因此,我有以下xml(items.xml),我想找到子节点项的属性,并在属性中迭代,如果在父节点级别找到类似的属性,则将其替换为子节点属性,并删除除名称以外的子属性

  <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>    
我可以获得子节点的属性名称,如下所示:

$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
现在,对于每个属性,我只需要返回父节点,检查是否存在类似的属性,并用子节点属性替换它

所以,我在找类似的东西

$model.SelectNodes("//item/@*") | foreach {($_.name).parentnode.parentnode.($_.name)} | <some code to replace parentnode attribute with child attribute>
如果这两个都可以在一个命令中完成,那将是非常棒的

也许我也试着在一条线上做很多事情

非常感谢您的指点!
不确定我在这里做错了什么,因为powershell不会为父节点使用抛出错误,但不会打印任何内容。所有有经验的程序员的帮助都是惊人的

您可以通过属性从属性获取父元素。因此,这是获得所需输出的一种可能方式:

$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) }
    }

可以通过属性从属性获取父元素。因此,这是获得所需输出的一种可能方式:

$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,请考虑,专门用于转换XML文件的专用语言。具体来说,您可以运行标识转换(按原样复制文档),然后使用

条件仅保留与
祖先::模型(祖父母)的属性名称匹配的属性。PowerShell可以创建.NET Framework类的对象,以运行XSLT 1.0脚本

XSLT(另存为.xsl,在PowerShell中作为参数传递)

命令行调用

Powershell.exe -File "C:\Path\To\PowerShell\Script.ps1"^
 "C:\Path\To\Input.xml" "C:\Path\To\XSLTScript.xsl" "C:\Path\To\Ouput.xml"
输出

<?xml version="1.0" encoding="utf-8"?>
<items>
  <model type="model1" name="default" price="12.12" date="some_value">
    <PriceData>
      <item name="watch" />
    </PriceData>
  </model>
  <model type="model2" name="default" price="12.12" date="some_value">
    <PriceData>
      <item name="toy" />
    </PriceData>
  </model>
  <model type="model3" name="default" price="12.12" date="some_value">
    <PriceData>
      <item name="bread" />
    </PriceData>
  </model>
</items>

<>代码> 因为您的标题提到修改XML,请考虑,专门用于转换XML文件的专用语言。具体来说,您可以运行标识转换(按原样复制文档),然后使用
条件仅保留与
祖先::模型(祖父母)的属性名称匹配的属性。PowerShell可以创建.NET Framework类的对象,以运行XSLT 1.0脚本

XSLT(另存为.xsl,在PowerShell中作为参数传递)

命令行调用

Powershell.exe -File "C:\Path\To\PowerShell\Script.ps1"^
 "C:\Path\To\Input.xml" "C:\Path\To\XSLTScript.xsl" "C:\Path\To\Ouput.xml"
输出

<?xml version="1.0" encoding="utf-8"?>
<items>
  <model type="model1" name="default" price="12.12" date="some_value">
    <PriceData>
      <item name="watch" />
    </PriceData>
  </model>
  <model type="model2" name="default" price="12.12" date="some_value">
    <PriceData>
      <item name="toy" />
    </PriceData>
  </model>
  <model type="model3" name="default" price="12.12" date="some_value">
    <PriceData>
      <item name="bread" />
    </PriceData>
  </model>
</items>


<代码> XSLT很好,我喜欢它,但是似乎没有其他人有相同的态度,因为他们认为学习太复杂:(同意@AntonKruglov!我在许多线程上回答了XSLT:Python、Java、PHP、Perl、VBA,但评论不一。大部分操作都是无声的。就像SQL用于数据库一样,我总是使用XSLT处理XML文件。走另一条路需要很多嵌套循环和逻辑。感谢Parfait,我想是时候学习XSLT了:)XSLT是好的,我喜欢它,但似乎没有其他人有相同的态度,因为他们认为太复杂,学习:(同意@AntonKruglov!我在许多线程上回答了XSLT:Python、Java、PHP、Perl、VBA,但评论不一。大部分操作都是无声的。就像SQL用于数据库一样,我总是使用XSLT处理XML文件。走另一条路需要很多嵌套循环和逻辑。感谢Parfait,我想是时候学习XSLT了:)很好!!非常感谢!!Ownerement是我一直在寻找的神奇功能,它就像一个符咒一样工作!你知道还有其他功能可以打印出属性“name&value”吗在父节点级别。另外,在Powershell中查找默认函数的最佳方法是什么,遗憾的是,周围似乎没有太好的Powershell文档。很好!!非常感谢har07!!OwnerElement是我一直在寻找的神奇函数,它工作得很好!你知道有没有其他函数可以直接打印父节点级别的属性“name&value”。另外,在Powershell中查找默认函数的最佳方法是什么,遗憾的是,似乎没有关于Powershell的优秀文档。
Powershell.exe -File "C:\Path\To\PowerShell\Script.ps1"^
 "C:\Path\To\Input.xml" "C:\Path\To\XSLTScript.xsl" "C:\Path\To\Ouput.xml"
<?xml version="1.0" encoding="utf-8"?>
<items>
  <model type="model1" name="default" price="12.12" date="some_value">
    <PriceData>
      <item name="watch" />
    </PriceData>
  </model>
  <model type="model2" name="default" price="12.12" date="some_value">
    <PriceData>
      <item name="toy" />
    </PriceData>
  </model>
  <model type="model3" name="default" price="12.12" date="some_value">
    <PriceData>
      <item name="bread" />
    </PriceData>
  </model>
</items>