web-dev-qa-db-ja.com

LINQとXDocument:XMLファイルを作成する方法は?

私はc#に3つのリストを持っています、変数名は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(element:Data)のlevel属性にはvalue = "2"があります。

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

したがって、上記のXML(element:Data)のlevel属性にはvalue = "1"があります。

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

したがって、上記のXML(要素:データ)のlevel属性にはvalue = "0"があります。

15
Rajesh Kumar G

正確には明確ではありません理由「レベル」属性は指定どおりですが、これにより、関連する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ビットはそれをトリッキーにします。正直に言うと、なぜそのようなものが必要なのかは明らかではありません...それなしで逃げることができれば、コードはよりクリーンになる可能性があります。

代替案の1つは、ドキュメントを作成することだと思いますなし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++);
}
30
Jon Skeet

どうですか:

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)));
2
as-cii