Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ and XDocument: How to create XML file?

I have a three List in c# ,the variable names are l_lstData1, l_lstData2, l_lstData3.

File structure is

<FileDetails>  
  <Date FileModified="29/04/2010 12:34:02" />   
  <Data Name="Data_1" DataList="India" Level="2" />   
  <Data Name="Data_2" DataList="chennai" Level="2" />   
  <Data Name="Data_3" DataList="hyderabad" Level="2" />   
  <Data Name="Data_4" DataList="calcutta" Level="2" />  
  <Data Name="Data_5" DataList="vijayawada" Level="1" /> 
  <Data Name="Data_6" DataList="cochin" Level="1" /> 
  <Data Name="Data_7" DataList="madurai" Level="0" />  
  <Data Name="Data_8" DataList="trichy" Level="0" />   
</FileDetails>

The Values of 3 Lists are as follows :

 l_lstData1[0] = "India";
 l_lstData1[1] = "chennai";
 l_lstData1[2] = "hyderabad";
 l_lstData1[3] = "calcutta"; 

so the level attribute of the above XML(element : Data) has value="2".

 l_lstData2[0] = "vijayawada";
 l_lstData2[1] = "cochin";      

so the level attribute of the above XML(element : Data) has value="1".

 l_lstData3[0] = "madurai";
 l_lstData3[1] = "trichy";      

so the level attribute of the above XML (element: Data) has value="0".

like image 267
Rajesh Kumar G Avatar asked Dec 30 '10 12:12

Rajesh Kumar G


People also ask

Can we use LINQ for XML?

LINQ to XML is a LINQ-enabled, in-memory XML programming interface that enables you to work with XML from within the . NET programming languages. LINQ to XML is like the Document Object Model (DOM) in that it brings the XML document into memory.

What is System XML LINQ?

LINQ to XML is an in-memory XML programming interface that enables you to modify XML documents efficiently and easily.

Which of the following option is created to retrieve data into XML using LINQ?

The LINQ to XML will bring the XML document into memory and allows us to write LINQ Queries on in-memory XML document to get the XML document elements and attributes. To use LINQ to XML functionality in our applications, we need to add "System. Xml. Linq" namespace reference.


2 Answers

It's not clear exactly why the "Level" attributes are as specified, but this would create the relevant XML for you:

// Used for side-effects in the XElement constructor. This is a bit icky. It's
// not clear what the "Name" part is really for...
int count = 1;

var doc = new XDocument(
    new XElement("FileDetails",
        new XElement("Date", new XAttribute("FileModified", DateTime.UtcNow)),
        l_lstData1.Select(x => new XElement("Data",
            new XAttribute("Name", "Data_" + count++),
            new XAttribute("DataList", x),
            new XAttribute("Level", 2))),
        l_lstData2.Select(x => new XElement("Data",
            new XAttribute("Name", "Data_" + count++),
            new XAttribute("DataList", x),
            new XAttribute("Level", 1))),
        l_lstData3.Select(x => new XElement("Data",
            new XAttribute("Name", "Data_" + count++),
            new XAttribute("DataList", x),
            new XAttribute("Level", 0)))));

It would probably be neater if you could extract the projections from a list item to its element, but the "Data_" + count bit makes that tricky. It's not clear why you need such a thing to be honest... if you could get away without that, the code could be cleaner.

I suppose one alternative would be to create the document without the Name attributes, and then populate them afterwards. For example:

private static IEnumerable<XElement> ProjectList(IEnumerable<string> list,
    int level)
{
    return list.Select(x => new XElement("Data",
        new XAttribute("DataList", x),
        new XAttribute("Level", level)));
}

then:

var doc = new XDocument(
    new XElement("FileDetails",
        new XElement("Date", new XAttribute("FileModified", DateTime.UtcNow)),
        ProjectList(l_lstData1, 2),
        ProjectList(l_lstData2, 1),
        ProjectList(l_lstData3, 0)));

int count = 1;
foreach (var element in doc.Descendants("Data"))
{
    element.SetAttributeValue("Name", "Data_" + count++);
}
like image 140
Jon Skeet Avatar answered Oct 05 '22 15:10

Jon Skeet


What about:

XDocument doc = new XDocument();

var total = (from a in list1 select new { Name = a, Level = 2 }).Concat(
             from b in list2 select new { Name = b, Level = 1 }).Concat(
             from c in list3 select new { Name = c, Level = 0 });

XElement root = new XElement("FileDetails", from i in Enumerable.Range(0, total.Count())
                                            let element = total.ElementAt(i)
                                            let name = new XAttribute("Name", String.Format("Data_{0}", i + 1))
                                            let level = new XAttribute("Level", element.Level)
                                            let datalist = new XAttribute("DataList", element.Name)
                                            select new XElement("Data", name, datalist, level),
                                            new XElement("Date", new XAttribute("FileModified", DateTime.Now)));
like image 33
as-cii Avatar answered Oct 05 '22 14:10

as-cii