XML Merge

Ask your Windows PowerShell-related questions, including questions on cmdlet development!
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
User avatar
sekou2331
Posts: 277
Meble kuchenne na zamówienie - na wymiar - Wrocław
Joined: Wed Aug 15, 2012 6:07 am

XML Merge

Post by sekou2331 »

I am trying to merge two xml's. I wanted to know the best way to do this. I want to overwrite anything that is the same from one file to the other. Does Powershell have any Tool or module that does this?

jvierra
Posts: 14358
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: XML Merge

Post by jvierra »

The simple answer is no. YOU cn load two XML files but you would have to defien what a "merge" means more fully.

PowerShell has the "[XML]" type accelerator that will load a file but you would then have to walk through the structures one element at a time and decide what is to be copied and what is to be skipped. This can be done but, again, a complete definition of what is to be merged needs to be decided.

Here is a good resource that can help you understand what XML is and how to work with it:

https://www.w3schools.com/xml/default.asp

User avatar
sekou2331
Posts: 277
Joined: Wed Aug 15, 2012 6:07 am

Re: XML Merge

Post by sekou2331 »

So what I am doing right now taking old.xml and comparing it to new.xml
1. Whatever XML Elements that are the same between the two files keep
2. If not the same XML Elements with the same text content only keep the XML Elements with the text content that are in old.xml
3. Lastly Any new XML Elements content and text content in the new.xml that is not in the old.xml keep
4. Output all changes to a new file.

Now I almost think I have the compare. But it is not completed(see below). Just trying to figure out the marge part and if I am going in the right direction with this.
  1. function Get-ChildNodes($xmlpath)
  2.  
  3. {
  4.  
  5.   $readXML = [xml](gc $xmlpath)
  6.  
  7.   $getNodes = $readXML.Settings
  8.  
  9.   foreach($node in $getNodes.ChildNodes)
  10.  
  11.   {
  12.  
  13.     $($node.Name)
  14.  
  15.   }
  16.  
  17. }
  18.  
  19.  
  20.  
  21. $file2 = Get-ChildNodes -xmlpath .\New.xml
  22.  
  23. $file1 = Get-ChildNodes -xmlpath .\Old.xml
  24.  
  25.  
  26.  
  27. function Compare-ChildNodes($oldFile, $newFile)
  28.  
  29. {
  30.  
  31.   Compare-Object -ReferenceObject $oldFile -DifferenceObject $newFile
  32.  
  33. }
  34.  
  35.  
  36.  
  37. Compare-ChildNodes -oldFile $file1 -newFile $file2

jvierra
Posts: 14358
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: XML Merge

Post by jvierra »

Compare won't work with XML. XML is hierarchical and Compare-Object only works on flat objects. Node equivalence is not a simple string match. Also what i does merge mean in this case?

Why use a function to call a function? It adds nothing and creates complexity that causes issues.

To compare XML nodes you will need to decide what the schema is representing and determine what a comparison means. In the end no nodes in two XML files will compare directly because of how the node objects are generated from the XML text.

First decide what is to be compared and what makes it equal. Use that to design code to implement this. You will have to do it for each different node type.

User avatar
sekou2331
Posts: 277
Joined: Wed Aug 15, 2012 6:07 am

Re: XML Merge

Post by sekou2331 »

In my script given I am getting the elements that are in both files and checking if they are the same then I will check the inner text. I have a function calling function because each function is responsible for one thing. As for the merge I am not to clear on your question but I just need to i guess recreate the file with new and old information by keeping the old information from the old file and adding new information from the new file that is not in the old file.

jvierra
Posts: 14358
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: XML Merge

Post by jvierra »

You are only getting one level which will never match and will not allow you any way to match. You must build your own code that compares what you need to compare and resolve what you mean by a match. XML is hierarchical and relational. Only the schema can tell you how to do what you want. You cannot just copy nodes from one XML to another. Copying or moving nodes is fairly complicated if you do not know XML.

I cannot give you much help without knowing the XML you are using and what you mean by "compare" and "merge".

User avatar
sekou2331
Posts: 277
Joined: Wed Aug 15, 2012 6:07 am

Re: XML Merge

Post by sekou2331 »

Below is an example of what both XML files will look like.

<?xml version="1.0" encoding="utf-8"?>

<Settings>

<Elements1>Text</Elements1>

<Elements2>Text</Elements2>
<Elements3>Text</Elements3>

<Elements4>Text</Elements4>
<Elements5>Text</Elements5>


<Elements6>Text</Elements6>

<Elements7>
<InnerElements>Text</InnerElements>
<InnerElements></InnerElements>
<InnerElements></InnerElements>
</Elements7>

<Elements8>
<InnerElements2>Text</InnerElements2>
<InnerElements2>Text</InnerElements2>
<InnerElements2>Text</InnerElements2>
</Elements8>
</Settings>

jvierra
Posts: 14358
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: XML Merge

Post by jvierra »

It doesn't say what you want to compare or how you want to compare the hierarchy. To compare only the top level under "settings" you can just extract all nodes under the root and check if they match.

$settings1 = $xml1.SelectNodes('//Settings')
$settings2 = $xml2.SelectNodes('//Settings')


Next I would enumerate the nodes in one and test the second for existence. If it is not in the second node set then save the node and process the remaining nodes. Last add all of the new nodes to the XML you want to merge into.

User avatar
sekou2331
Posts: 277
Joined: Wed Aug 15, 2012 6:07 am

Re: XML Merge

Post by sekou2331 »

I added the files and what I want them to look like just a small example below. I just want to add anything that is new in the new file and merge it with the old file. But i want o also check the inner text. The Get-ChildNodes function gets the elements. But it looks like you are saying i need to iterate. How then do I then merge?

Old.xml
  1. <Settings>
  2.  
  3. <Elements1>Text</Elements1>
  4.  
  5. <Elements2>Text</Elements2>
  6.  
  7. <Elements3>Text</Elements3>
  8.  
  9. <Elements4>Text</Elements4>
  10.  
  11. <Elements5>Text</Elements5>
New.xml
  1. <Settings>
  2.  
  3. <NewElements1>Text</Elements1>
  4.  
  5. <NewElements1>Text</Elements1>
  6.  
  7. <Elements1>DifferentText</Elements1>
  8.  
  9. <Elements2>DifferentText</Elements2>
  10.  
  11. <Elements3>DifferentText</Elements3>
  12.  
  13. <Elements4>Text</Elements4>
  14.  
  15. <Elements5>Text</Elements5>
  16.  
  17. </Settings>
Merged_Output
  1. <Settings>
  2.  
  3. <NewElements1>Text</Elements1>
  4.  
  5. <NewElements1>Text</Elements1>
  6.  
  7. <Elements1>Text</Elements1>
  8.  
  9. <Elements2>Text</Elements2>
  10.  
  11. <Elements3>Text</Elements3>
  12.  
  13. <Elements4>Text</Elements4>
  14.  
  15. <Elements5>Text</Elements5>
  16.  
  17. </Settings>
Attachments
Old.xml
(527 Bytes) Downloaded 6 times
New.xml
(697 Bytes) Downloaded 5 times
Meraged_Output.xml
(657 Bytes) Downloaded 4 times

jvierra
Posts: 14358
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: XML Merge

Post by jvierra »

Sorry but your files are not legal XML and cannot be loaded. Also what you are asking doesn't make much sense.

These are not real files - they are hand made examples. YOU need to post real XML and not just something you have tried to invent as an example.

Post Reply