LINQ и XDocument: как создать файл XML? - PullRequest
15 голосов
/ 30 декабря 2010

У меня есть три списка в c #, имена переменных: l_lstData1, l_lstData2, l_lstData3.

Структура файла

<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>

Значения 3 списков следующие:

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

поэтому атрибут уровня вышеуказанного XML (элемент: Data) имеет значение = "2".

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

поэтому атрибут уровня вышеуказанного XML (элемент: Data) имеет значение = "1".

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

поэтому атрибут уровня вышеуказанного XML (элемент: Data) имеет значение = "0".

Ответы [ 2 ]

30 голосов
/ 30 декабря 2010

Непонятно точно почему атрибуты "Level" такие, как указано, но это создаст для вас соответствующий XML:

// 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)))));

Возможно, было бы лучше, если бы вы могли извлекать проекции из элемента списка в его элемент, но бит "Data_" + count усложняет задачу. Непонятно, зачем вам такая вещь, если честно ... если бы вы могли обойтись без этого, код мог бы быть чище.

Полагаю, одной альтернативой было бы создать документ без атрибутов Name, а затем заполнить их. Например:

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)));
}

, то:

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++);
}
2 голосов
/ 30 декабря 2010

А как же:

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)));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...