xmldiff - Extract differences between two XML files that contains directory structures, using linQ? -
i'm implementing client-server program synchronize files between computers. @ point, when client connects server, xml file contains directory structure of location must synchronized server sent server. if not first time when client connects, on server exists such xml files there must found differences between 2 files , request client ones files have been changed or new. problem is... how can find differences between xml's. have 2 xml samples(one xml can have , 1gb).
first xml (source.xml):
<?xml version='1.0'?> <rootdirectory name="new folder" datecreated="5/20/2013 7:16:32 pm"> <folder name="new folder1" > <file name="new text document11.txt" /> <file name="new text document12.txt" /> </folder> <file name="new text document1.txt" /> </rootdirectory>
second xml (changed.xml):
<?xml version="1.0" encoding="utf-8"?> <rootdirectory name="new folder" datecreated="5/20/2013 7:15:50 pm"> <folder name="new folder1"> <file name="new text document11.txt" /> <file name="new text document12.txt" /> </folder> <folder name="new folder2"> <folder name="new folder21"> <file name="new text document211.txt" /> <folder name="new folder211"> <file name="new text document2111.txt" /> <folder name="new folder2111"> <file name="new text document21111.txt" /> </folder> </folder> </folder> <file name="new text document21.txt" /> </folder> <file name="new text document1.txt" /> </rootdirectory>
i found example uses linq xml http://www.codeproject.com/articles/45233/diff-in-xml-files-with-linq, xml structure used there different, , not me much. given fact can have tag folder
, file
nested inside other nodes..i don't know how find differences ...
can give me idea?
thank you!
best regards, oana
a possible solution algorithm this:
- extract folders old file
- extract folders new file
- fetch new folders list except method => new = list2.except(list1)
- fetch same folders list intersect method => possiblechanges = list2.intersect(list1)
- compare content changed lists
- repeat of (recursion or iteration) levels
example code:
var xml1 = @"<?xml version='1.0'?> <rootdirectory name=""new folder"" datecreated=""5/20/2013 7:16:32 pm""> <folder name=""new folder1"" > <file name=""new text document11.txt"" /> <file name=""new text document12.txt"" /> </folder> <file name=""new text document1.txt"" /> </rootdirectory>"; var xml2 = @"<?xml version=""1.0"" encoding=""utf-8""?> <rootdirectory name=""new folder"" datecreated=""5/20/2013 7:15:50 pm""> <folder name=""new folder1""> <file name=""new text document11.txt"" /> <file name=""new text document12.txt"" /> <file name=""new text document13.txt"" /> </folder> <folder name=""new folder2""> <folder name=""new folder21""> <file name=""new text document211.txt"" /> <folder name=""new folder211""> <file name=""new text document2111.txt"" /> <folder name=""new folder2111""> <file name=""new text document21111.txt"" /> </folder> </folder> </folder> <file name=""new text document21.txt"" /> </folder> <file name=""new text document1.txt"" /> </rootdirectory>"; var xmldoc1 = xdocument.parse(xml1); var xmldoc2 = xdocument.parse(xml2); var f1 = allfolders(xmldoc1.root); var f2 = allfolders(xmldoc2.root); var newfolders = f2.except(f1); var samefolders = f2.intersect(f1); // new folders, content new => no further checks needed! newfolders.dump(); // check if content of same folders has changed foreach (var samefolder in samefolders) { var oldcontent = foldercontent(xmldoc1.root.descendants("folder").where (r => r.attribute("name").value == samefolder).tolist()); var newcontent = foldercontent(xmldoc2.root.descendants("folder").where (r => r.attribute("name").value == samefolder).tolist()); var newfiles = newcontent.except(oldcontent); } private list<string> foldercontent(ienumerable<xelement> nodes) { var files = new list<string>(); nodes.tolist().foreach(n => files.addrange(n.elements("file").select (x => x.attribute("name").value).tolist())); return files; } private list<string> allfolders(xelement node) { var folders = node.descendants("folder").tolist().select (e => e.attribute("name").value).tolist(); return folders; }
output:
//changed folders new folder2 new folder21 new folder211 new folder2111 // new files new folder 1 newtextdocument13.txt
Comments
Post a Comment