3

I have the following XML. How to read the root node attribite value and it's decendents using LINQ? I am trying to read "dId" and "dTime" from root node, "id" from Customer element and Order number.

<?xml version="1.0" encoding="utf-8" ?>
 <Customers dId="wqwx" dTime="10-9-09 11:23">
   <Customer id="1">
      <Orders>
        <Order number="22" status="ok">
      </Orders>
   </Customer>
 </Customers>

I tried the following code but it doesn't work.

XDocument doc= XDocument.Load(@"C:\Customers.xml");
var q = from c in doc.Descendants("Customers")
        select new        
          {   
           dID = c.Attribute("dId"),
           dTime = c.Attribute("dTime");
          }

5 Answers 5

1

first, fix your xml (<Order .... />) then, your linq should look like this....

// .Elements(...) selects all elements of type "Customer"
    var q = from c in xDoc.Elements("Customers") 
    select new
    {
        dID = c.Attribute("dId"), 
        dTime = c.Attribute("dTime")
    }; 

you should dl LinqPad... it lets you do Linq queries on the fly, even agains SQL databases. Then, once you get the results you want, copy and past your linq into your source code.

Sign up to request clarification or add additional context in comments.

1 Comment

I just downloaded Linqpad: absolutely amazing!
1

You have to end the order tag with: />

xDoc.Descendants("Customers") should work as well as xDoc.Elements("Customers").

Chris, is there a specific advantage to using .Elements?

1 Comment

the .Elements lets you query on the element for child-elements with the specified element-type (in this case, "Customers")
0

You can't use LINQ to access the root tag. The code below does what you want (I included a well formed xml file as well):

using System;
using System.Linq;
using System.Xml.Linq;

namespace ReadXmlSpike
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Reading file...");
            XDocument doc = XDocument.Load("Customers.xml");
            var customers =
                new
                    {
                        DID = (string) doc.Element("Customers").Attribute("did"),
                        DTime = (DateTime) doc.Element("Customers").Attribute("dTime"),
                        Customers = from customerxml in doc.Descendants("Customer")
                                    select
                                        new
                                            {
                                                ID = (string)customerxml.Attribute("id"),
                                                Orders = from orderxml in customerxml.Descendants("Order")
                                                         select
                                                             new
                                                                 {
                                                                     Number =(string) orderxml.Attribute("number")
                                                                 }
                                            }
                    };
            Console.WriteLine("Customersfile with id: {0} and time {1}",customers.DID,customers.DTime);
            foreach (var customer in customers.Customers)
            {
                Console.WriteLine("Customer with id {0} has the following orders:",customer.ID);
                foreach (var order in customer.Orders)
                {
                    Console.WriteLine("Order with number {0}",order.Number);
                }
            }
            Console.ReadLine();
        }
    }
}

and the xml file:

<?xml version="1.0" encoding="utf-8" ?>
<Customers did="www" dTime="10-09-09 11:23">
  <Customer id="1">
    <Orders>
      <Order number="22" status="ok"/>
      <Order number="23" status="bad"/>
    </Orders>
  </Customer>
  <Customer id="2">
    <Orders>
      <Order number="24" status="ok"/>
      <Order number="25" status="bad"/>
    </Orders>
  </Customer>
</Customers>

Comments

0
    XDocument d = XDocument.Parse(@"<?xml version='1.0' encoding='utf-8' ?>
        <Customers dId='wqwx' dTime='10-9-09 11:23'>
            <Customer id='1'>      
                <Orders>        
                    <Order number='22' status='ok'/>      
                </Orders>   
            </Customer> 
        </Customers>");
    var cu = d.Root.Elements().Where(n => n.Name == "Customer");


    var c = from cc in cu
            select new
            {
                dId = cc.Document.Root.Attribute("dId").Value,
                dTime = cc.Document.Root.Attribute("dTime").Value,
                ID = cc.Attribute("id").Value,
                number = cc.Element("Orders").Element("Order").Attribute("number").Value
            };

    foreach (var v in c)
    {
        Console.WriteLine("dId \t\t= {0}", v.dId);
        Console.WriteLine("dTime \t\t= {0}", v.dTime);
        Console.WriteLine("CustomerID \t= {0}", v.ID);
        Console.WriteLine("OrderCount \t= {0}", v.number);
    }

Console Output:
================================
dId = wqwx
dTime = 10-9-09 11:23
CustomerID = 1
OrderCount = 22
请按任意键继续. . .

Comments

0

It does not work the way you wrote it: while printing the above code would complain about anonymous type.

However, with this simple modified version d.Document.Root.Attribute("dId").Value; you can assign it to a string.

1 Comment

The OP's code doesn't have a d variable created, nor is there an accepted answer for this question. In what reference is your answer to, and how is it different from the cc.Document.Root.Attribute("dId").Value answer provided by Laurel.Wu?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.