将类实例作为值添加到字典中

时间:2010-06-22 04:04:05

标签: c# xml

我有一个xml文件“Sample.xml”

  <RootElement>
    <Children>
       <Child Name="FirstChild" Start="0" End="2">
          <Sibling Name="Test1" />
          <Sibling Name="Test2" />
          <AdditionalSibling Name="Add_Test_1" />
          <AdditionalSibling Name="Add_Test_2" />
          <MissingSibling Name="Miss_Test_1" />
          <MissingSibling Name="Miss_Test_2" /
     </Child>

     <Child Name="SecondChild" Start="0" End="2">
          <Sibling Name="Test3" />
          <Sibling Name="Test4" />
     </Child>
     <Child Name="ThirdChild" Start="0" End="2">
          <Sibling Name="Test5" />
          <Sibling Name="Test6" />
      </Child>
      <Child Name="FourthChild" Start="0" End="2">
          <Sibling Name="Test7" />
          <Sibling Name="Test8" />
      </Child>
      <Child Name="FifthChild" Start="0" End="2">
          <Sibling Name="Test9" />
          <Sibling Name="Test10" />
      </Child>
      <Child Name="SixthChild" Start="0" End="2">
          <Sibling Name="Test11" />
          <Sibling Name="Test12" />
      </Child>

      <MatchedChilds>
         <Child Name="FirstChild" />
         <Child Name="SecondChild" />
         <Child Name="ThirdChild" />
         <Child Name="FourthChild" />
         <Child Name="FifthChild" />
         <Child Name="SixthChild" /> 
     </MatchedChilds>
   </Children>
 </RootElement>

一个“SampleClass”类

public class SampleClass
{
    string Start;
    string End;
    List<string> Siblings;
    List<string> AdditionalSiblings;
    List<string> MissingSiblings;
     public SampleClass()
     {
        Start= "";
        End = "";
        Siblings = new List<string>();
        AdditionalSiblings = new List<string>();
        MissingSiblings = new List<string>();
     }
    public SampleClass( string St, string En,List<string> S, List<string> AS, List<string> MS)
    {
        Start= St;
        End = En;
        Siblings = S;
        AdditionalSiblings = AS;
        MissingSiblings = MS;
    }

}

在另一个班级我宣布了Dictonary Like

 Dictionary<string, SampleClass> m_dictSample = new Dictionary<string, SampleClass>();

我需要用文件的内容填写这个dictonary ..

我正在使用Xml Linq ..

XDocument l_XDOC = XDocument.Load(Application.StartupPath + "\\Sample.xml");

m_dictSample = (from element in l_XDOC.Descendants("Child")
                        group element by element.Attribute("Name").Value into KeyGroup
                        select KeyGroup )
                        .ToDictionary(grp => grp.Key,
                                      grp => new
                                          SampleClass(grp.Attributes("Start").ToList()[0].Value.ToString(),
                                          grp.Attributes("End").ToList()[0].Value.ToString(),
                                          grp.Descendants("Sibling").Attributes("Name").Select(l_Temp => l_Temp.Value).ToList(),
                                          grp.Descendants("AdditionalSibling").Attributes("Name").Select(l_Temp => l_Temp.Value).ToList(),
                                          grp.Descendants("MissingSibling").Attributes("Name").Select(l_Temp => l_Temp.Value).ToList()));

此查询适用于上述文件。

但是如果文件有多个具有相同名称的Element,或者没有“start”和“end”属性的元素会产生异常, 执行查询。

我对以下几行有疑问

     grp.Attributes("Start").ToList()[0].Value.ToString(),
     grp.Attributes("End").ToList()[0].Value.ToString()

请给我一个更好的方法来做到这一点

我需要用Dictonary的内容填充listView,如

S.no       Child              Siblings                Additional Siblings            Missing Siblings

 1         FirstChild         Test1,Test2             Add_Test_1,Add_Test_2           Miss_Test_1,Miss_Test_2

 2         SecondChild        Test3,Test4

 3         ThirdChild         Test5,Test6

现在我正在使用for循环

请给我一个更好的方法来做这件事。

2 个答案:

答案 0 :(得分:4)

您不能使用必须使用Lookup集合的词典

字典要求每个键都有1-1映射到唯一值。

您正在寻找的是Lookup系列。

有关详细信息,请参阅this

答案 1 :(得分:1)

鉴于您编写查询的方式,如果您有两个具有相同名称的Child元素,我不明白为什么您会收到异常。如果他们的数据只是组合到你的字典中的单个键实例。要解决在Start属性不存在时收到的异常,只需执行conditional operator测试? :,查看是否从您的属性查询中返回了结果。这就是说下面的代码应该适用于您的免责声明,因为这不起作用并不意味着它是最佳实践。在很多方面,我自己都是LINQ新手。

Dictionary<string, SampleClass> dict =
    (from element in xDoc.Descendants("Child")
              group element by element.Attribute("Name").Value
                  into kGrp
                  select kGrp)
            .ToDictionary(grp => grp.Key,
            grp => new SampleClass
            {
                Start = grp.Attributes("Start").Count() > 0
                        ? grp.Attributes("Start")
                             .ToList()[0].Value.ToString()
                        : String.Empty
                ,End = grp.Attributes("End").Count() > 0
                        ? grp.Attributes("End")
                             .ToList()[0].Value.ToString()
                        : String.Empty
                ,Siblings =
                    grp.Descendants("Sibling")
                        .Attributes("Name")
                        .Select(l_Temp => l_Temp.Value).ToList()
                ,AdditionalSiblings =
                    grp.Descendants("AdditionalSibling")
                        .Attributes("Name")
                        .Select(l_Temp => l_Temp.Value).ToList()
                ,MissingSiblings =
                    grp.Descendants("MissingSibling")
                        .Attributes("Name")
                        .Select(l_Temp => l_Temp.Value).ToList()
            });