scharby (2) [Avatar] Offline
#1
My program is based on Chapter11.CreateObjectsFromXml().

I can only 'load' the first AnswerList Answer element value. I am expecting (trying) to load all three Answer elements.

I hope there is easy solution for this, I've spend many hours & countless variations to no avail. Assistance would be greatly appreciated.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Diagnostics;

namespace QAcSharp1
{
public class Action
{
public int ID { get; set; }
public String ActionType { get; set; }
public String Content { get; set; }
public IEnumerable<Answer> AnswerList { get; set; }
}

public class Answer
{
public string Text { get; set; }
}

class Program
{
static void Main(string[] args)
{
string xml = @"<ActionList>
<Action id='1' type='Question'>
<Content value ='What type of vehicle did you purchase?'/>
<AnswerList>
<Answer value='Car' />
<Answer value='Truck' />
<Answer value='SUV' />
</AnswerList>
</Action>
</ActionList>";

XElement actionListXML = XElement.Parse(xml);

// build our objects using query expressions and object initializers
var actionList =
from actionElement in actionListXML.Elements("Action")
select new Action
{
ID = (int)actionElement.Attribute("id"),
ActionType = (string)actionElement.Attribute("type"),
Content = (string)actionElement.Element("Content").Attribute("value"),
AnswerList = from answerListElement in actionElement.Elements("AnswerList")
select new Answer
{
Text = (string)answerListElement.Element("Answer").Attribute("value")
}
};

foreach (Action a in actionList)
{
Debug.WriteLine((int)a.ID);
Debug.WriteLine((string)a.ActionType);
Debug.WriteLine((string)a.Content);
foreach (Answer ans in a.AnswerList)
{
Debug.WriteLine((string)ans.Text);
}
}
Console.WriteLine("hit any key....");
Console.ReadLine();
}
}
}
fabrice.marguerie (224) [Avatar] Offline
#2
Re: Building objects using query expressions & object initializers
Hello Mark,

You made a simple mistake.
In your XML there is one AnswerList element that contains three Answer elements.
In your code, you are trying to process several AnswerList elements, with one Answer element for each.

If you change your code in the following way, it works fine:

[pre]from actionElement in actionListXML.Elements("Action")
select new Action
{
ID = (int)actionElement.Attribute("id"),
ActionType = (string)actionElement.Attribute("type"),
Content = (string)actionElement.Element("Content").Attribute("value"),
AnswerList =
from answerListElement in actionElement.Elements("AnswerList")
from answerElement in answerListElement.Elements("Answer")
select new Answer
{
Text = (string)answerElement.Attribute("value")
}
};[/pre]
I left "from answerListElement..." in place to handle the case where there is no AnswerList element.
If you are sure that the AnswerList element exists, you can simplify the query as follows:

[pre]from actionElement in actionListXML.Elements("Action")
select new Action
{
ID = (int)actionElement.Attribute("id"),
ActionType = (string)actionElement.Attribute("type"),
Content = (string)actionElement.Element("Content").Attribute("value"),
AnswerList =
from answerElement in actionElement.Element("AnswerList").Elements("Answer")
select new Answer
{
Text = (string)answerElement.Attribute("value")
}
};[/pre]
Fabrice
scharby (2) [Avatar] Offline
#3
Re: Building objects using query expressions & object initializers
Hello Fabrice,

Thank you very much for your immediate response. I burned up the better part of two days trying to figure this out.

Your first solution with (2) 'from' statements is probably most appropriate. I had no idea you could 'chain' two 'from' statements together.

The second solution, I know I tried that approach, but I was going around in circles for so long who knows. Sometimes, the seemingly simplest problems can be the hardest.

Your book is the best, Thanks for your help.