Click here to Skip to main content
15,893,722 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hello , I'm new in C#/LINQ.

I have 2 xmls with a common value element. I'm combining them in C#.
Doc1.xml:
XML
<line_item_data>
	<product_Category>TKM</product_Category>
	<technology>T6FFP</technology>
	<line_item>Name_1</line_item>
	<release>2013.04</release>
	<description>Maintenance.</description>
</line_item_data>


Doc2.xml:
XML
<productVersionDetails>
    <version_id>4737</version_id>
    <product>Name_1</product>
    <version>2</version>
    <status>Retired</status>
    <owner_name>Pepe Q.</owner_name>
    <type>PML</type>
    <os>Any</os>
 </productVersionDetails>


I'm merging 2 XML per value of their Element line_item and product and only the elements with type = "PML" through a Join in LINQ :

C#
XElement query = new XElement("ArrayOfProductVersionDetails",
              from bl in XElement.Load(@"doc1.xml").Elements("line_item_data") 
             join g in XElement.Load(@"doc2.xml").Elements("productVersionDetails")
                     on (string)bl.Element("line_item") equals (string)g.Element("product")
              where ((string)g.Element("type")).Equals("PML")

 
             select new XElement("product_item",
               new XElement("version_id", (string)g.Element("version_id")),
               new XElement("technology", (string)bl.Element("technology")),
               new XElement("product", (string)g.Element("product")),
               new XElement("version", (string)g.Element("version")),
               new XElement("status", (string)g.Element("status")),
               new XElement("type", (string)g.Element("type")),
               new XElement("owner_name", (string)g.Element("owner_name")),
               new XElement("description", (string)bl.Element("description")),
               new XElement("os", (string)g.Element("os"))

             )

          );
           
           query.Save(@"XML_Merged.xml");

The problem is n the final XML appears duplicate Elements:

XML_Merged.xml:

XML
</ArrayOfProductVersionDetails>
<product_item>
  <version_id>4737</version_id>
    <product>Name_1</product>
    <version>2</version>
    <status>Retired</status>
    <owner_name>Pepe Q.</owner_name>
    <type>PML</type>
    <os>Any</os>
    <technology>T6FFP</technology>
    <description>Maintenance</description>
</product_item>
<product_item>
  <version_id>4737</version_id>
    <product>Name_1</product>
    <version>2</version>
    <status>Retired</status>
    <owner_name>Pepe Q.</owner_name>
    <type>PML</type>
    <os>Any</os>
    <technology>T6FFP</technology>
    <description> Maintenance</description>
</product_item>
</ArrayOfProductVersionDetails>

I would like to do something like distinct() statement in SQL or other better way.How could I solve this?
Posted
Updated 25-Feb-14 21:07pm
v2

1 solution

First of all, I advice you not to cast values explicitly. Instead use 'Value' property as in:
bl.Element("line_item").Value equals g.Element("product").Value


As an answer to your question, there are several ways. You can do this by making your subqueries having distinct values according to the join condition, or the result can be made distinct according to a field what you want. I would prefer the first way.

C#
var q1 = (from bl in XElement.Load(@"doc1.xml").Elements("line_item_data").GroupBy(i1 =>
                            i1.Element("line_item").Value).Select(i1 => i1.First())
                      join g in XElement.Load(@"doc2.xml").Elements("productVersionDetails").GroupBy(i1 =>
                            i1.Element("product").Value).Select(i1 => i1.First())
                              on bl.Element("line_item").Value equals g.Element("product").Value
                      select new XElement("product_item",
                        new XElement("version_id", g.Element("version_id").Value),
                        new XElement("technology", bl.Element("technology").Value),
                        new XElement("product", g.Element("product").Value),
                        new XElement("version", g.Element("version").Value),
                        new XElement("status", g.Element("status").Value),
                        new XElement("type", g.Element("type").Value),
                        new XElement("owner_name", g.Element("owner_name").Value),
                        new XElement("description", bl.Element("description").Value),
                        new XElement("os", g.Element("os").Value)
                      )).ToList();



But it still depends on according to which field you want to make it distinct. Make your decision according to your aim. In the example, I have just chosen the first record of duplicates (duplicated in its xml, not the other file), but it still may not be aligned with your intention.
 
Share this answer
 
Comments
Kinna-10626331 26-Feb-14 7:38am    
Thanks!! Vedat Ozan, I was focused on distinct that I didn't realize about group by statement.
Vedat Ozan Oner 26-Feb-14 8:10am    
you are welcome :)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900