简体   繁体   English

使用LINQ从XML读取对象

[英]Read from XML to an object using LINQ

I am trying to read from an XML and enter into an object list. 我正在尝试从XML读取并输入对象列表。 My XML is 我的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>

This is my object class: 这是我的对象类:

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; }
    }
}

I am able to get Name and Role, but how can I get QA List? 我可以获得名称和角色,但是如何获得质量检查清单? I tried writing a select within the query but that didnt seem to work. 我尝试在查询中编写一个选择,但似乎没有用。

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

You can do the following: 您可以执行以下操作:

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

Note that you don't need to access Value property if you are using explicit cast, whole point of using explicit cast is to avoid possible exceptions, if you use the Value property then explicit cast become redundant because if the element wasn't found it will throw the exception anyway... 请注意,如果您正在使用显式强制转换,则不需要访问Value属性,使用显式强制转换的整个目的是避免可能的异常,如果您使用Value属性,则显式强制转换将变得多余,因为如果找不到元素无论如何都会抛出异常...

In situations like this, I find it to be extremely helpful to split-up a complex LINQ expression into multiple sub-expressions, if only to help with development and debugging. 在这种情况下,我发现将复杂的LINQ表达式拆分为多个子表达式非常有帮助,即使只是为了帮助开发和调试也是如此。

Without knowing more about the structure of your real xml data, here are some ideas: 在不进一步了解真实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
        } 
    }        
}

Again, this isn't the "cleanest" approach, and certainly there are more concise ways to express this in LINQ. 同样,这不是“最干净”的方法,当然还有更简洁的方法可以在LINQ中表达它。 The point is, you have quite a few more options for break-points/debugging, allowing you explore the objects you are working with. 关键是,您有更多的断点/调试选项,可以浏览正在使用的对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM