Solved

Compare/combine attributes in 2 xml files

Posted on 2011-03-04
7
614 Views
Last Modified: 2013-11-11
Hello Experts,

I have 2 xml files as below:

test1.xml:
 <Values>
      <Value>
        <Field name="ID1" value="1000" />
        <Field name="ID2" value="300000" />
        <Field name="Description" value="Description 1" />
        <Field name="CurrentAmount" value="374564.32" />
      </Value>
 <Value>
        <Field name="ID1" value="1000" />
        <Field name="ID2" value="304000" />
        <Field name="Description" value="Description 2" />
        <Field name="CurrentAmount" value="404.52" />
  </Value>
</Values>
 
test2.xml:
<Values>
      <Value>
        <Field name="ID1" value="1000" />
        <Field name="ID2" value="300000" />
        <Field name="PastAmount" value="79727.60" />
      </Value>
      <Value>
        <Field name="ID1" value="1000" />
        <Field name="ID2" value="300010" />
        <Field name="PastAmount" value="44152.11" />
      </Value>
      <Value>
        <Field name="ID1" value="1000" />
        <Field name="ID2" value="304000" />
        <Field name="PastAmount" value="79323.08" />
      </Value>
</Values>

Using LINQ, is there any way to get the difference between CurrentAmount and PastAmount based on the match of the values of ID1 and ID2?
For example,
If ID1 = 1000 and ID2 = 300000, I want to get the difference of 374564.32 - 79727.60.

Thank you very much in advance.
-Chu
0
Comment
Question by:Zhaolai
7 Comments
 
LVL 11

Accepted Solution

by:
jasonduan earned 500 total points
ID: 35039811
try this:
XDocument doc1 = XDocument.Load("test1.xml");
XDocument doc2 = XDocument.Load("test2.xml");

var list1 = from x in doc1.Descendants("Value")
	select new
	   {
	   ID1 = (from y in x.Descendants("Field") 
		  where y.Attribute("name").Value == "ID1" 
		  select Convert.ToInt32(y.Attribute("value").Value)).FirstOrDefault(),
	   ID2 = (from y in x.Descendants("Field") 
		  where y.Attribute("name").Value == "ID2" 
		  select Convert.ToInt32(y.Attribute("value").Value)).FirstOrDefault(),
	   CurrentAmount = (from y in x.Descendants("Field") 
		 where y.Attribute("name").Value == "CurrentAmount" 
		 select Convert.ToDouble(y.Attribute("value").Value)).FirstOrDefault()
	   };
var list2 = from x in doc2.Descendants("Value")
	select new
	{
	ID1 = (from y in x.Descendants("Field") 
	   where y.Attribute("name").Value == "ID1" 
	   select Convert.ToInt32(y.Attribute("value").Value)).FirstOrDefault(),
	ID2 = (from y in x.Descendants("Field") 
	   where y.Attribute("name").Value == "ID2" 
	   select Convert.ToInt32(y.Attribute("value").Value)).FirstOrDefault(),
	PastAmount = (from y in x.Descendants("Field") 
		  where y.Attribute("name").Value == "PastAmount" 
		  select Convert.ToDouble(y.Attribute("value").Value)).FirstOrDefault()
	};

var diffList = from x in list1
	   join y in list2 on x.ID1 + "_" + x.ID2 equals y.ID1 + "_" + y.ID2
	   select new { ID1 = x.ID1, ID2 = x.ID2, DiffAmount = x.CurrentAmount - y.PastAmount };

foreach (var item in diffList)
{
	System.Diagnostics.Debug.WriteLine(item.ID1 + " " + item.ID2 + " " + item.DiffAmount);
}

Open in new window

0
 
LVL 17

Author Comment

by:Zhaolai
ID: 35039961
WOW. Amazed. Great answer! Thanks a bunch.
0
 
LVL 12

Expert Comment

by:kumar754
ID: 35040594
Compressed Version:


XDocument xdoc1 = XDocument.Load("test1.xml");
XDocument xdoc2 = XDocument.Load("test2.xml");

var list1 = from test1 in xdoc1.Descendants("Value")
          join test2 in xdoc2.Descendants("Value")
            on {ID1=test1.Attribute("ID1").Value, ID2=test1.Attribute("ID2").Value}
            equals {ID1=test2.Attribute("ID1").Value, ID2=test2.Attribute("ID2").Value}
          select new {
            ID1 = test1.Attribute("ID1").Value,
            ID2 = test1.Attribute("ID2").Value,
            DiffAmount = Convert.ToDouble(test1.CurrentAmount) - Convert.ToDouble(test2.PastAmount)
          };


0
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 
LVL 17

Author Comment

by:Zhaolai
ID: 35041640
@kumar754, thank you for your post.

But when I put your code into test, it does not work, simply because "ID1" and "ID2" are values of attributes, not attribute names, meaning that test1.Attribute("ID1").Value will generate notorious error: Object reference not set to an instance of an object.

Also test1.CurrentAmount and test2.PastAmount are not defined.
Also you need to have "new" on both sides of the "equals".
0
 
LVL 12

Expert Comment

by:kumar754
ID: 35043777
@Author:

yeah i didn't tested the code. As I expect these are some of spell checks you already know based on the level of expertize and the code you are trying to achieve. I gave out a solution/concept that you can implement. There is always an alternate way to solve a problem and you figure out which one works out best for you.
0
 

Expert Comment

by:South Mod
ID: 35115082
All,
 
Following an 'Objection' by kumar754 (at http://www.experts-exchange.com/Q_26865359.html) to the intended closure of this question, it has been reviewed by at least one Moderator and is being closed as recommended by the Expert.
 
At this point I am going to re-start the auto-close procedure.
 
Thank you,
 
SouthMod
Community Support Moderator
0

Featured Post

Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
In this video I am going to show you how to back up and restore Office 365 mailboxes using CodeTwo Backup for Office 365. Learn more about the tool used in this video here: http://www.codetwo.com/backup-for-office-365/ (http://www.codetwo.com/ba…
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …

813 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now