Compare xml files using C# LINQ
In this article you will learn how to compare two xml files using C# LINQ (Language Integrated Query one of the great features in C# 3.0 release) .Imagine a scenario where you are consuming a third party web service for online book selling site. Every day you may need to update your site if any new book is launched and also you want to sync with your existing information. I am going to create a simple class called Book with three properties. (You can download the article source code from the bottom of the page.)
public class Book
{
public Book()
{
}
public int BookID { get; set; }
public String Name { get; set; }
public double Price { get; set; }
public Book(int bookId, string name, double price)
{
this.BookID = bookId;
this.Name = name;
this.Price = price;
}
}
The next step is to create custom comparer class which implements IEqualityComparer. The comparer class returns true if both bookId’s are equal.
public class BookComparer : IEqualityComparer<Book>
{
public bool Equals(Book x, Book y)
{
return (x.BookID == y.BookID);
}
public int GetHashCode(Book book)
{
return book.BookID.GetHashCode();
}
}
Sample XML files
Book_A.xml
<?xml version="1.0" encoding="utf-8" ?> <Books> <Book bookId="100" name="Asp.Net" price = "230" /> <Book bookId="101" name="C#" price = "200" /> <Book bookId="102" name="Silverlight" price = "300" /> <Book bookId="103" name="MFC Book" price = "300" /> </Books>
Book_B.xml
<?xml version="1.0" encoding="utf-8" ?> <Books> <Book bookId="100" name="Asp.Net" price = "230" /> <Book bookId="101" name="C#" price = "200" /> <Book bookId="102" name="Silverlight" price = "300" /> <Book bookId="104" name="WPF" price = "200" /> <Book bookId="105" name="WCF" price = "200" /> </Books>
Result.XML
<?xml version="1.0" encoding="utf-8"?> <Books> <Book bookId="100" name="Asp.Net" price="230" /> <Book bookId="101" name="C#" price="200" /> <Book bookId="102" name="Silverlight" price="300" /> <Book bookId="103" name="MFC Book" price="300" /> <Book bookId="104" name="WPF" price="200" /> <Book bookId="105" name="WCF" price="200" /> </Books>
Default.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
IEnumerable<Book> bookA = LoadXML("Books_A.xml");
IEnumerable<Book> bookB = LoadXML("Books_B.xml");
BookComparer oComparer = new BookComparer();
var comparerList = bookA.Except(bookB, oComparer).ToList();
List<Book> result = new List<Book>();
result.AddRange(comparerList);
result.AddRange(bookB);
result = (from book in result
orderby book.BookID ascending
select book).ToList<Book>();
XElement xElement = new XElement("Books",
from book in result
select new XElement("Book",
new XAttribute("bookId", book.BookID.ToString()),
new XAttribute("name", book.Name),
new XAttribute("price", book.Price)
)
);
xElement.Save(Server.MapPath("~/XML/result.xml"));
}
IEnumerable<Book> LoadBooksFromXML(string fileName)
{
XElement xml = XElement.Load(Server.MapPath("~/XML/" + fileName));
var query = (from book in xml.Descendants("Book")
orderby (int)book.Attribute("bookId") ascending
select new Book(
(int)book.Attribute("bookId"),
(string)book.Attribute("name") != null ? (string)book.Attribute("name") : string.Empty,
(double)book.Attribute("price"))
);
return query;
}
Code Explanation
IEnumerable<Book> bookA = LoadXML(“Books_A.xml”);
LoadXML method load xml file and return a collection of Book class
BookComparer oComparer = new BookComparer(); //The BookComparer class instantiate a new object
var comparerList = bookA.Except(bookB, oComparer).ToList();
The above statement will compare the items in Books_A.xml with Books_B.xml and return a collection of items which is not found in Book_B.xml
Based on the above XML files the return list would be some thing like below
<Book bookId=”103″ name=”MFC Book” price = “300″ />
Finally we need to merge the items in to a new list and save as result.xml file.
Create a new List for hold the result list
List<Book> result = new List<Book>();
result.AddRange(comparerList); //result list
result.AddRange(bookB); //book_B.xml collection.
//sort by book id ascending
result = (from book in result
orderby book.BookID ascending
select book).ToList<Book>();
//Save as new xml file.
XElement xElement = new XElement(“Books”,
from book in result
select new XElement(“Book”,
new XAttribute(“bookId”, book.BookID.ToString()),
new XAttribute(“name”, book.Name),
new XAttribute(“price”, book.Price)
)
);
xElement.Save(Server.MapPath(“~/XML/result.xml”));
You can download the entire article from here or copy paste this URL
http://www.4shared.com/file/232888750/82ac9ddf/XMLComparer.html
Hope this help and If you have any comments, please feel free to write your feedback.
Thanks
Deepu
