1

I need help please I have two XML files,They have the same id("name")I want to get difference between them. if I have extra nodes in Xml file_1, so it will go to diff. xml file according to only id. I have wrote som code but I don't know how it will be if; I know we can do in Microsoft Diff and Patch tool but I want a different code: here is my code:

    public static void Main()
    {
           //fields
         const string XML1 = @"File_1.xml";
         const string XML2 = @"File_2.xml";
         const string ResultFile = @"ResultFile.xml";
         XmlDocument doc1 = new XmlDocument();
         doc1.Load(XML1);
         XmlDocument doc2 = new XmlDocument();
         doc2.Load(XML2);

         for(var d = 0; d < doc1.SelectNodes("root/data").Count; d++)
         {
             var child = doc1.SelectNodes("root/data")[d];
            if (I don't know …..) {

           }
         }

XML fil_1

<root>
  <data name="senChangePassword" xml:space="preserve">
    <value>Byt lösenord</value>
    <comment>Sprint 02 - Jessica</comment>
  </data>
  <data name="senChangesWereSuccessfullySaved" xml:space="preserve">
    <value>Ändringarna är sparade</value>
    <comment>Sprint 02 - Jessica</comment>
  </data>
  <data name="senChangeUserSettings" xml:space="preserve">
    <value>Ändra uppgifter</value>
    <comment>Sprint 02 - Jessica</comment>
  </data>
  <data name="senCompareWith" xml:space="preserve">
    <value>Jämför</value>
    <comment>Sprint 02 - Jessica</comment>
  </data>
  <data name="senCreatedQuestions" xml:space="preserve">
    <value>Skapade frågor</value>
    <comment>Sprint 02 - Jessica</comment>
  </data>
</root>

** XML file_2**

<root>
  <data name="senChangePassword" xml:space="preserve">
    <value>Change Password</value>
    <comment>Sprint 02 - Jessica</comment>
  </data>
  <data name="senChangesWereSuccessfullySaved" xml:space="preserve">
    <value>Saved changes</value>
    <comment>Sprint 02  Jessica</comment>
  </data>
  <data name="senCompareWith" xml:space="preserve">
    <value>Compare</value>
    <comment>Sprint 02 - Jessica</comment>
  </data>
</root>

XML file_result

<root>
  <data name="senChangeUserSettings" xml:space="preserve">
    <value>Ändra uppgifter</value>
    <comment>Sprint 02 - Jessica</comment>
  </data>
  <data name="senCreatedQuestions" xml:space="preserve">
    <value>Skapade frågor</value>
    <comment>Sprint 02 - Jessica</comment>
  </data>
</root>
jdweng
  • 33,250
  • 2
  • 15
  • 20
Osama
  • 71
  • 5
  • 1
    See : https://stackoverflow.com/questions/57885510/how-to-get-only-changes-of-two-xml-files-in-c-sharp-context/57886190#57886190 – jdweng Sep 24 '19 at 07:19
  • It is difficult code for me , it is advanced and I don't anderstand xml.linq, I need a code withe just " using system.xml" . I want to compare only node id not space or inner text. – Osama Sep 24 '19 at 07:28
  • This is quite a challenging problem to solve. Consider investing in a solution like DeltaXML rather than trying to tackle this yourself. – Michael Kay Sep 24 '19 at 07:33
  • but in your link code , result file will be both files for my xml files, I don't need that. Can you change in your code to get the same result file, because I have no idea about linq. – Osama Sep 24 '19 at 07:43
  • The solution is much simpler in Xml Linq using a left outer join. – jdweng Sep 24 '19 at 08:51
  • How it will be please! Which Changes should be – Osama Sep 24 '19 at 08:56

1 Answers1

1

Simple version (if you don't care about performance or memory size):

using System.Linq;

// ....
var nodes1 = doc1.SelectNodes("root/data");
var children1 = new List<XmlNode>();
int i = 0;
foreach(XmlNode a in nodes1) { children1[i++] = a; }
var nodes2 = doc2.SelectNodes("root/data");
var children2 = new List<XmlNode>();
i = 0;
foreach(XmlNode b in nodes2) { children2[i++] = b; }
var result = new List<XmlNode>();

for(var d = 0; d < children1.Count; d++)
         {
             var child = children1[d];
             var match = children2.FirstOrDefault(x=>
                 XElement.Parse(x.OuterXml).ToString() == XElement.Parse(child.OuterXml).ToString());
            if (match == null) {
               result.Add(child);
           }
         }

and dump result nodes into result file as best you see fit

LongChalk
  • 783
  • 8
  • 13
  • You might also want to take a look at https://stackoverflow.com/questions/6442123/in-c-how-do-i-convert-a-xmlnode-to-string-with-indentation-without-looping for understanding the duality between XmlNode and its matching string. It's almost the same thing. – LongChalk Sep 24 '19 at 08:12
  • 1
    Thanks for answer there are tow wrongs in code this row: var result = List(); and in this row: var match = children2.FirstOrDefault(…...); the fel is XMLNodeList does not contain a defination for (FirstOrDefault). What should I do here, – Osama Sep 24 '19 at 08:41
  • 1
    you need to add the namespace "using System.Linq;" – Dhaval Patel Sep 24 '19 at 09:41
  • I have provided it but it does not work. what shoild do please – Osama Sep 24 '19 at 10:27
  • Thanks for the note @Osama - that's what I get for writing code on the fly in stackoverflow. shame on me :o) hope this helps... – LongChalk Oct 03 '19 at 09:27