Powershell - 混合2个XML文件

时间:2013-06-12 12:10:42

标签: xml powershell import export add

我已经查看了现有主题,但没有找到任何内容。 我有2个XML文件,除了一些行几乎相同。 目的是从第一个XML获取值,将其添加到第二个XML中,然后第二个将删除第一个XML文件。

这是第一个文件的结构

<configuration >
<protocol>
 <NATIVE>
 </NATIVE>
 <ICAP>
 </ICAP>
 <RPC>
  <ClientList>
    <items>
      <item value="X.X.X.X">
      <item value="A.A.A.A">
    </items>
  </ClientList>
</configuration>

和第二个文件:

<configuration >
<protocol>
 <NATIVE>
 </NATIVE>
 <ICAP>
 </ICAP>
 <RPC>
  <ClientList>
    <items>
      <item value>

    </items>
  </ClientList>
</configuration>

目的是获取“Item Value = ...”的行并将其插入第二个XML文件中。对于可能存在的所有行

我尝试将值保存到TXT文件中,然后像这样从TXT导入:

$xmlpath1 = "c:\temp\configuration.xml"
$xmlpath2 = "c:\configuration1.xml"
$xmlpath3 = "c:\temp\output.txt"
[xml]$xd= Get-Content $xmlpath1
[xml]$xd2= Get-Content $xmlpath2

$rpc=($xd.configuration.protocol.RPC.ClientList.items.item  )
$rpc2=($xd2.configuration.protocol.RPC.ClientList.items.item  )

foreach($value in $rpc2){

$value.value >> "c:\temp\output.txt"

}
$txt = get-content $xmlpath3 
foreach($line in $txt){
$a=$xd.configuration.protocol.RPC.ClientList.items["item"]
$new=$xd.CreateElement("item")
[void]$a.AppendChild($new)
$a.setattribute("value","$line")
 $xd.Save($xmlpath1)

}

但不是得到:

<ClientList>
    <items>
      <item value="X.X.X.X">
        <item value="A.A.A.A"/>
        <item value="B.B.B.B"/>
        <item value="C.C.C.C"/>
      </item>
    </items>
  </ClientList>

我得到了:

<ClientList>
    <items>
      <item value="C.C.C.C">     <== Last entry read by PS...
        <item />
        <item />
        <item />

      </item>
    </items>
</ClientList>
如果测试很多方法不同,但都没有成功。 如果您有任何建议,那就太棒了!

2 个答案:

答案 0 :(得分:0)

这是一种方法,你的文件包含无效的xml,修复它们并尝试一下。

$newXml = @"
<configuration>
<protocol>
<NATIVE></NATIVE>
<ICAP></ICAP>
 <RPC>
  <ClientList>
    <items>
        $(
            $xd.SelectNodes("//configuration/protocol/RPC/ClientList/items").InnerXml
            $xd2.SelectNodes("//configuration/protocol/RPC/ClientList/items").InnerXml
        )
    </items>
  </ClientList>
   </RPC>
   </protocol>
</configuration>
"@

$newXml | Out-File $xmlpath2
Remove-Item $xmlpath1 -Force

答案 1 :(得分:0)

你可以尝试这样的事情。它会从test1.xml中的clientlist节点获取所有项元素,并将它们添加到test2.xml

$xml1 = [xml](Get-Content .\Desktop\test1.xml)
$xml2 = [xml](Get-Content .\Desktop\test2.xml)

#foreach item-nodes with value attribute in xml1
$xml1.SelectNodes("//configuration/protocol/RPC/ClientList/items/item[@value]") | % { 
    #check if item already exists. If not, add
    if($xml2.SelectSingleNode("//configuration/protocol/RPC/ClientList/items/item[@value='$($_.value)']") -eq $null) {
        $xml2.SelectSingleNode("//configuration/protocol/RPC/ClientList/items").AppendChild($xml2.CreateElement("item")).SetAttribute("value",$_.value)
    }
}

$xml2.Save("C:\Users\graimer\Desktop\test2.xml")

我之前和之后都添加了xml文件,因为在它们是有效的xml之前我必须修改它们(关闭一些元素)。

test1.xml(之前)

<configuration>
<protocol>
 <NATIVE></NATIVE>
 <ICAP></ICAP>
 <RPC>
  <ClientList>
    <items>
      <item value="X.X.X.X" />
      <item value="A.A.A.A" />
    </items>
  </ClientList>
</RPC>
</protocol>
</configuration>

test2.xml(之前)

<configuration >
<protocol>
 <NATIVE>
 </NATIVE>
 <ICAP>
 </ICAP>
 <RPC>
  <ClientList>
    <items>
    </items>
  </ClientList>
</RPC>
</protocol>
</configuration>

test2.xml(之后)

<configuration>
  <protocol>
    <NATIVE>
    </NATIVE>
    <ICAP>
    </ICAP>
    <RPC>
      <ClientList>
        <items>
          <item value="X.X.X.X" />
          <item value="A.A.A.A" />
        </items>
      </ClientList>
    </RPC>
  </protocol>
</configuration>