tags:

views:

201

answers:

2

I've an xml file "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>

And a Class "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;
    }

}

and in another class i've declared a Dictonary Like

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

i need to fill this dictonary with the contents of the file ..

I'm using Xml Linq for this..

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

This query is working properly for the above described file.

But if the file have more than one Element with same name, or an element with no "start" and "end" attribute make an exception while executing the query.

I've problem with the following lines

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

please give me a better way to do this

And i need to fill a listView with the contents of the Dictonary like

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

now i'm using for loop for this

please give me a better way to do this..

A: 

Given the way that you have written your query I don't see why you'd be getting an exception if you had two Child elements with the same name. If anything their data would just get combined into a single key instance in your dictionary. To fix the exception you receive when a Start attribute doesn't exist just do a conditional operator test ? : to see if results were returned from your attribute query. That said the below code should work for you with the disclaimer that just because this works doesn't mean it's best practice. In many ways I am a LINQ neophyte myself.

        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()
                    });
ahsteele
@ ahsteele: Thank you....please explain how to add the data to the listview?
Pramodh
@Pramodh I'd recommend splitting your question up. You've got quite the wall of code there and I didn't even notice the second part until I came and checked on your comment.
ahsteele
+4  A: 

You can't use a Dictionary you have to use a Lookup collection

Dictionaries require that each key has a 1-1 mapping to a unique value.

What you're looking for is a Lookup collection.

See this for more info.

Evan Plaice