使用LINQ从XML读取对象

时间:2014-05-07 23:37:30

标签: c# xml linq

我正在尝试从XML读取并进入对象列表。 我的XML是

<User>
    <Name>John</Name>
    <Role>Admin</Role>
    <QAList>
        <QA>
            <Question> Question 1 </Question>
            <Answers>
                <Answer> Answer 1 </Answer>
                <Answer> Answer 2 </Answer>
                <Answer> Answer 3 </Answer>
            </Answers>
        </QA>
    </QAList>
</User>

这是我的对象类:

public class ListQuestionAnswers: INotifyPropertyChanged
{
    private List<QuestionAnswer> _questionAnswer;
    public List<QuestionAnswer> QuestionAnswerList
    {
        get { return _questionAnswer; }
        set { _questionAnswer = value; }
    }

    private string _name;
    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }

    private string _role;
    public string Role
    {
        get { return _role; }
        set { _role = value; }
    }
}

public class QuestionAnswer
{
    public string _question;
    public List<AnswerList> _answers;

    public string Question
    {
        get { return _question; }
        set { _question = value; }
    }

    public List<AnswerList> Answers
    {
        get { return _answers; }
        set { _answers = value; }
    }
}

public class AnswerList
{
    private string _answer;

    public string Answer
    {
        get { return _answer; }
        set {_answer = value; }
    }
}

我能够获得姓名和角色,但我怎样才能获得QA列表?我尝试在查询中编写一个选择,但这似乎没有用。

XDocument xmlDoc = XDocument.Load(@"C:\Test\Sample.xml");
var files = (from x in xmlDoc.Elements("User")
             select new TestCasesViewModel
             {
                 Name = (string)x.Element("Name").Value ?? string.Empty,
                 Role = (string)x.Element("Role").Value ?? string.Empty
             }).ToList();

2 个答案:

答案 0 :(得分:1)

您可以执行以下操作:

var files = (from x in xmlDoc.Elements("User")
             select
             new TestCasesViewModel
                  {
                      Name = (string)x.Element("Name") ?? string.Empty,
                      Role = (string)x.Element("Role") ?? string.Empty,
                      QuestionAnswerList = 
                          x.Descendants("QA")
                          .Select(q => new QuestionAnswer
                          {
                              Question = (string)q.Element("Question"),
                              Answers = q.Descendants("Answer").Select(a => new AnswerList { Answer = (string)a}).ToList()

                          }).ToList()
                   }).ToList();

请注意,如果使用显式强制转换,则无需访问Value属性,如果使用Value属性,则使用显式强制转换的完整点是为了避免可能的异常然后显式转换变得多余,因为如果找不到该元素,它将抛出异常......

答案 1 :(得分:0)

在这种情况下,我发现将复杂的LINQ表达式拆分为多个子表达式非常有用,只是为了帮助开发和调试。

在不了解真实xml数据结构的情况下,以下是一些想法:

XDocument xmlDoc = XDocument.Load(@"C:\Test\Sample.xml");

var users = xmlDoc.Elements("User");

foreach(var user in users)
{
    var qaList = user.Element("QAList");

    foreach(var qa in qaList.Elements("QA"))
    {
        //at this point, you should have access the <Question> node e.g.
        string question = qa.Element("Question").Value;

        //and the list of answers would be similar to before
        var answers = qa.Element("Answers");

        foreach(var answer in answers.Elements("Answer"))
        {
            //now answer.Value should be the text of the answer
        } 
    }        
}

同样,这不是“最干净”的方法,当然还有更简洁的方法在LINQ中表达这一点。关键是,你有更多的断点/调试选项,允许你探索你正在使用的对象。

相关问题