LINQ to XML : Creating complex XML through LINQ

LINQ to XML : Creating complex XML through LINQ

  • Comments 14

We can generate hierarchical object graph in our memory though LINQ. To be more realistic we can bring data from relational database. So if we consider Northwind database and use LINQ to SQL to bring all the Customers and their Orders and Order Details the query would look like,

 

 

//LINQ to SQL way to get data from database

var q = from c in db.Customers

        select new

        {

            CId = c.CustomerID,

            Orders = from o in c.Orders

                     select new

                     {

                         OID = o.OrderID,

                         Qty = from od in o.Order_Details

                               select new { Qty = od.Quantity }

                     }

        };

 

 

 

So what I am trying to do here is that, I am trying to fetch CustomerId from Customers table and OrderId from Orders table and Quantity from Order Details table. It is bringing 3 level deep data for me and storing it to memory.

 

By using XElement and XAttribute I will create a single XML stream. Which will look like,

 

<?xml version="1.0" encoding="utf-8"?>

<customers>

  <customer id="ALFKI" country="Germany" contactName="Maria Anders" contactTitle="Sales Representative">

    <Orders id="10643" date="1997-08-25T00:00:00">

      <items>

        <item price="45.6000" quantity="15" />

        <item price="18.0000" quantity="21" />

        <item price="12.0000" quantity="2" />

      </items>

    </Orders>

    <Orders id="10692" date="1997-10-03T00:00:00">

      <items>

        <item price="43.9000" quantity="20" />

      </items>

    </Orders>

 

…….

 

To achieve this I have to write a very simple query like syntax based on the query I have written earlier,

 

var query = new XElement("customers",

           from c in db.Customers                       

           select

               new XElement("customer",

                   new XAttribute("id", c.CustomerID),

                   new XAttribute("country", c.Country),

                   new XAttribute("contactName", c.ContactName),

                   new XAttribute("contactTitle", c.ContactTitle),

 

                   from o in c.Orders

                   select new XElement("Orders",

                       new XAttribute("id", o.OrderID),

                       new XAttribute("date", o.OrderDate),

                            new XElement("items",

 

                       from od in o.Order_Details

                       select new XElement("item",

                               new XAttribute("price", od.UnitPrice),

                               new XAttribute("quantity", od.Quantity))))));

 

 

It looks complex because it is one liner but actually it is very simple. This will give you the exact XML output mentioned earlier.

 

Namoskar!!!

Leave a Comment
  • Please add 6 and 7 and type the answer here:
  • Post
  • We can generate hierarchical object graph in our memory though LINQ. To be more realistic we can bring

  • Based on my previous post if I have to filter the list of customers only in the country “US” and create

  • Welcome to the forty-first Community Convergence. The big news this week is that we have moved Future

  • How did you get the <?xml ...?> processing instruction to be part of the XML you generated.

  • @Tim,

    When you call .Save() method it automatically gets added. Else you could also use XDocument and then initialize XProcessingIn.... to add you own. For details please visit my

    http://blogs.msdn.com/wriju/archive/2008/02/28/linq-to-xml-creating-complete-xml-document.aspx

  • there is no way to do this:

     Dim contacts as XElement =  _

       <contacts>

         <%= From c In contacts  _

             Select _

               <>

                 <!-- contact -->

                 <name><%= c.<name>.Value %> </name>

                 <%= c.<phone> %>

                 <address><%= c.<address> %> </address>

         </>

         %>

       </contacts>

    in C#??

  • Thanks for this post Wriju, it was usefull.

    All the best from UK mate ;)

    Grant and Greg, two frustrated developers :)

  • - <Transfers SessionID="123456789>

    - <Transfer Id="123456789" Duration="0.30">

     <Vehicle ID="123456789" Type="Shuttle" Image="Shuttle.jpg" Description="Fish" NumberReq="3" />

    - <RampComponents>

     <Component Name=" S - Ramp" ID="1" />

     <Component Name=" M - Ramp" ID="2" />

     </AccessibilityComponents>

    - <Passengers>

     <Adults>2</Adults>

    - <Children>

     <Child Age="2" />

     <Child Age="3" />

     </Children>

     </Transfer>

     </Transfers>

    I am trying to get the two mulit elements out

    My Code so far

    Dim m = From mi In xdoc.<Transfers> _

                  Select New Menu() With { _

                       .SessionID = mi.@SessionID, _

                       .TransferID = CLng(mi.<Transfer>.@ID), _

                       .Duration = mi.<Transfer>.@Duration, _

                       .NumberRequired = mi.<Transfer>.@NumberReq, _

                       .VehicleID = Convert.ToInt32(mi.<Vehicle>.@ID), _

                       .VehicleType = mi.<Vehicle>.@Type, _

                       .childrenAges = From c In mi.<Child> _

                        Select New ChildrenAges() With { _

                               .Age = c.@Age _

                           } _

                       .links = From l In mi.<Component> _

                           Select New Link() With { _

                              .ID = l.@ID, _

                              .Name = l.@Name _

                   } _

               }

    If could help it would be appreciated

  • Mark,

    I would be more than happy to help you. Could you please explain more on what exactly the output be?

  • The article was really useful..

    But I am facing a problem with my application, The xml document gets updated only after the application finish running.. so in my datagrid I do not get the updated information from xml file at the first time.

    Please do help me with this issue.

  • Mekha Nair,

    You may need to call the grid generation after the upload.

  • Hi;

    This is like the most beneficial Linq to XML code sample ever.

    I have to create the XML doc below, I tried so many things and I must say I am very new to Lınq to Xml, I met it like yesterday.

    I have written a code with the help of your code here is my query

    var query = new XElement("PRODUCTCATALOG",

              from urun in db.TBLP1URUNs

              select

                  new XElement("PRODUCT",

                      new XAttribute("ID", urun.ID),

                      new XAttribute("D1", urun.MODEL),

                      new XAttribute("D2", urun.URUNACIKLAMA),

                      new XAttribute("L1", urun.TBLP1URUNKATEGORI.TREENAME),

                      from resim in urun.TBLP1URUNRESIMs

                      select new XElement("IMG", resim.FILE_NAME),

                      new XAttribute("EAN", urun.STOKKODU),

                      new XAttribute("ATP", 1),//STOKMIKTARI

                      new XAttribute("DM3", urun.DESI),

                      from ozellikler in urun.TBLP1OZELLIK_URUNs

                      select new XElement("S",

                          new XAttribute("L", ozellikler.TBLP1OZELLIK.TBLP1OZELLIKTIPI.TIPI),

                          new XAttribute("V", ozellikler.TBLP1OZELLIK.OZELLIK))

                          )                      

               );

    below is the XML doc i want to create:

    <?xml version="1.0" encoding="utf-8"?>

    <PRODUCTCATALOG xmlns="webservice.arenaopen.com/.../ProductCatalogSchema.xsd">

    <PRODUCT>

       <ID>BX3-00048</ID>

       <D1>Some data 5</D1>

       <D2>SOMEDATA1</D2>

       <L1>OEM</L1>

       <L2>OEMMOUWRL</L2>

       <BR>Some data 6</BR>

       <KDV>18</KDV>

       <IMG>BX3-00048.jpg</IMG>

       <EAN>882224763769</EAN>

       <ATP>50+</ATP>

       <DM3>0,67</DM3>

       <S>

         <L>Some data 2</L>

         <V>OPTIK</V>

       </S>

       <S>

         <L>Somedata3</L>

         <V>3,0</V>

       </S>

       <S>

         <L>Fare bağlantısı</L>

         <V>KABLOSUZ RF</V>

       </S>

       <S>

         <L>Renk</L>

         <V>SIYAH</V>

       </S>

       <S>

         <L>Programlanabilir Tuş Sayısı</L>

         <V>3</V>

       </S>

       <S>

         <L>Satış Garanti Süresi (ay)</L>

         <V>24</V>

       </S>

     </PRODUCT>

    </PRODUCTCATALOG>

    Do you think my code is ok?And in addition how do I make it a page now with this query?

  • thank you so much for your post, it really enlightened me I managed to do what i wanted to do with your help.

  • Very nice and clean article. Thanks a lot.

Page 1 of 1 (14 items)