2

I'm trying to turn an XML document into a List<> with a predefined Class

My xml dataset TestData.xml

<Objects>
    <Object ID="1">
        <ItemOne>"Hickory"</ItemOne>
        <ItemTwo>"Dickory"</ItemTwo>
        <ItemThree>"Dock"</ItemThree>
    </Object>

    <Object ID="2">
        <ItemOne>"The"</ItemOne>
        <ItemTwo>"Mouse"</ItemTwo>
        <ItemThree>"Went"</ItemThree>
    </Object>
</Objects>

The Main program

class Program
{
    static void Main(string[] args)
    {

        XElement TestData = XElement.Load("TestData.xml");

       List<Test> myTest = new List<Test>(from d in TestData.Descendants("Objects")
                                     select new Test(
                                         d.Element("ItemOne").Value.ToString(),
                                         d.Element("ItemTwo").Value.ToString(),
                                         d.Element("ItemThree").Value.ToString()));

        myTest.ForEach(i => Console.WriteLine("{0} {1} {2}", i.itemOne, i.itemTwo, i.itemThree));

        Console.ReadLine();
    }


}

The class I'm trying to form the data to

class Test
{
    public string itemOne { get; set; }
    public string itemTwo { get; set; }
    public string itemThree { get; set; }
}

I would like to get out

Hickory Dickory Dock
The Mouse went

but I end up getting nothing. It looks like the LINQ Query finds the data but never assigns it to the List<Test> myTest, the value shows as null in the debugger. I'm not sure what I'm doing wrong.

I want to convert the XML to List<Test> so I can randomly rearrange through the objects. I was going to just use int[] array and sort by "ID" but I don't know the actual length of the array and want to assign it on the fly so I am forced to do a list<>. I am open to other suggestions of accomplishing this.

5
  • Don't you mean List<Test> myTest? Commented Dec 6, 2012 at 9:24
  • @ZevSpitz I think it's List<Quiz> because the constructor in the LINQ query is also for class Quiz. The list constructor is maybe wrong though. Commented Dec 6, 2012 at 9:29
  • 2
    d.Element("ItemOne").Value.ToString() - Value is itself a string, so calling ToString is redundant. Also, it's more robust to cast the XElement to string -- (string)d.Element("ItemOne") -- rather then retrieve the Value, because if there is no such element .Element returns null, and .Value will cause a NullReferenceException. See here. Commented Dec 6, 2012 at 9:33
  • sorry the "Quiz" was a typo, but thanks for the other advice it actually solved a different problem I was having and looks cleaner too. Commented Dec 6, 2012 at 9:41
  • I edited it to fix the typo Quiz. Thanks Commented Dec 6, 2012 at 9:43

2 Answers 2

5

Without having it tested, I think you should write TestData.Descendants("Object") instead of TestData.Descendants("Objects"). The parameter for Descendants must match the name of the nodes you want to select.

Sign up to request clarification or add additional context in comments.

Comments

2

You are already at the root that is Objects

Do this

from d in TestData.Descendants("Object")
                               --------

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.