2

I want to get the question and answer values using C#, but before that I want to get the ID I need. I'm using this XML:

<root>
  <information>
    <name>Tasks</name>
    <date>15-05-2005</date>
  </information>
  <tasks>
      <task>
        <id>1</id>
        <question>Here comes question 1</question>
        <answer>Answer 1</answer>
      </task>
      <task>
        <id>2</id>
        <question>Here comes question 2</question>
        <answer>Answer 2</answer>
      </task>
      <task>
        <id>3</id>
        <question>Here comes question 3</question>
        <answer>Answer 3</answer>
      </task>
</root>

C# code:

XDocument tasks;
int TheIdINeed = 2;
string quest = "";
string answ = "";

On form load:

tasks = XDocument.Load(leveltoload);
var status = tasks.Element("level").Element("information");
quest = tasks.Element("root").Element("tasks").Element("task").Element("question").Value; // It returns me the first task data, but I need to load data with required Id (int TheIdINeed = ...)

I'm sorry, my English isn't good.

1
  • Perfect English Commented Nov 14, 2016 at 13:29

3 Answers 3

3

You could use this

string id = "2";
var qa = doc.Descendants("tasks").Elements("task")
                       .Where(x => x.Element("id").Value == id).FirstOrDefault();
if (qa != null)
{
   var question = qa.Element("question").Value;
   var answer = qa.Element("answer").Value;
}

If you need to get the question and answers outside of this scope, I suggest creating a class that will hold the data. For example,

public class QuestionAnswer
{
    public string ID { get; set; }
    public string Question { get; set; }
    public string Answer { get; set; }
}


var qa = doc.Descendants("tasks").Elements("task")
            .Where(x => x.Element("id").Value == id)
            .Select(x => new QuestionAnswer() 
                    {
                      ID = "2",
                      Question = x.Element("question").Value,
                      Answer = x.Element("answer").Value
                    });

You could improve the above by using a Dictionary to store the Question/Answer pair but it's just an example to give you an idea. in case your QuestionAnswer class is more complicated than just those two properties.

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

2 Comments

This is slightly inefficient, as you could use the FirstOrDefualt overload that takes a predicate.
@It'sNotALie. - Good addition. +1 for your answer for that.
2
var empty = new XElement("e");
var sID = id.ToString();
var element = tasks.Descendants("task")
                   .FirstOrDefault(x => ((string)x.Element("id")) == sID);
string quest = (string)((element ?? empty).Element("question"));
string answ = (string)((element ?? empty).Element("answer"));

1 Comment

There's no such thing as XElement.Empty (unless you mean IsEmpty but that's not a static property).
1

you can get all data to dictionary so you won't repeat conversion to string

var res = tasks.Descendants("task")
    .Select(x => x.Elements().ToDictionary(e => e.Name.ToString(), e => (string)e.Value))
    .FirstOrDefault(x => x["id"] == id);

res["question"]
res["answer"]

but if there tasks without questions or answers in your xml you have to check if res is contains key before you will get value, or use TryGetValue:

string question;
res.TryGetValue("question", out question);

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.