在PowerShell上将节点从一个XML导入到另一个XML

时间:2016-11-18 13:26:29

标签: xml powershell

我需要将名为“ProjectOptions”的节点从default.xml复制到original.xml而不修改任何其他内容:

Original.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<KEYS>
  <KEY ObjectName="computername_user" RegObjectType="0">
    <KEYS>
      <KEY ObjectName="Desktop" RegObjectType="0">
        <KEYS>
          <KEY ObjectName="Settings" RegObjectType="0">
            <KEYS>
              <KEY ObjectName="PrinterDefault" RegObjectType="0">
                <VALUES>
                  <VALUE ObjectName="PrinterOrientation" Value="2" ValueType="4" />
                </VALUES>
              </KEY>
              <KEY ObjectName="ProjectOptions" RegObjectType="0">
                <VALUES>
                  <VALUE ObjectName="ShowWelcomeMsg" Value="0" ValueType="4" />
                </VALUES>
              </KEY>
            </KEYS>
          </KEY>
        </KEYS>
      </KEY>
    </KEYS>
  </KEY>
</KEYS>

default.xml中

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<KEYS>
  <KEY ObjectName="computername_user" RegObjectType="0">
    <KEYS>
      <KEY ObjectName="Desktop" RegObjectType="0">
        <KEYS>
          <KEY ObjectName="Settings" RegObjectType="0">
            <KEYS>
              <KEY ObjectName="PrinterDefault" RegObjectType="0">
                <VALUES>
                  <VALUE ObjectName="PrinterOrientation" Value="2" ValueType="4"/>
                </VALUES>
              </KEY>
              <KEY ObjectName="ProjectOptions" RegObjectType="0">
                <VALUES>
                  <VALUE ObjectName="GSAddBatchOptionDialogRect" Value="381,203,981,629" ValueType="2"/>
                  <VALUE ObjectName="GSHeadNodeName" Value="" ValueType="2"/>
                  <VALUE ObjectName="GSIsAdvancedMode" Value="1" ValueType="4"/>
                  <VALUE ObjectName="GSRemoteSchedulerPlatform" Value="" ValueType="2"/>
                  <VALUE ObjectName="GSSchedulerName" Value="" ValueType="2"/>
                  <VALUE ObjectName="GSShowFrequentlyUsedBatchOptions" Value="1" ValueType="4"/>
                  <VALUE ObjectName="GSUserName" Value="" ValueType="2"/>
                  <VALUE ObjectName="ShowWelcomeMsg" Value="0" ValueType="4"/>
                </VALUES>
              </KEY>
            </KEYS>
          </KEY>
        </KEYS>
      </KEY>
    </KEYS>
  </KEY>
</KEYS>

我试过这样的事情

$xml = [xml](Get-Content "C:\Temp\original.xml")
$xmld = [xml](Get-Content "C:\Temp\default.xml")
$Child=$xml.KEYS.KEY.KEYS.KEY.KEYS.KEY.KEYS.KEY[1].VALUES.VALUE
$xml.DocumentElement.InsertAfter($XML.ImportNode($xmld.SelectSingleNode("//KEY[@ObjectName = 'ProjectOptions']"), $true), $Child)
$xml.Save("C:\Temp\save.xml")

但它以“参考节点不是此节点的子节点”结束。 请告诉我哪里出错了。 感谢。

2 个答案:

答案 0 :(得分:3)

您尝试在DocumentElement节点下插入导入的节点,但$Child不是该节点的直接子元素。您需要在InsertAfter()的父节点上调用$Child方法。

改变这个:

$xml.DocumentElement.InsertAfter($XML.ImportNode($xmld.SelectSingleNode("//KEY[@ObjectName = 'ProjectOptions']"), $true), $Child)

进入这个:

$Child.ParentNode.InsertAfter($XML.ImportNode($xmld.SelectSingleNode("//KEY[@ObjectName='ProjectOptions']"), $true), $Child)

问题就会消失。

作为旁注,您可能希望使用XPath表达式而不是点符号来选择$Child

$Child = $xml.SelectSingleNode('//VALUE[@ObjectName="ShowWelcomeMsg"]')

答案 1 :(得分:1)

找到一种简单的方法:

$xmlPO = $xml.SelectNodes("//KEY[@ObjectName='ProjectOptions']")
$xmldPO = $xmld.SelectNodes("//KEY[@ObjectName='ProjectOptions']")
$xmlPO.set_InnerXML($xmldPO.innerXML)
$xml.Save($dpath)​