C# xml解析-代码重构问题

C# xml解析-代码重构问题,c#,xml,linq-to-xml,xelement,C#,Xml,Linq To Xml,Xelement,我有以下xml: <?xml version="1.0" encoding="utf-8"?> <RootData> <PassResult> <FirstOne>P1</FirstOne> <SecondOne>P2</SecondOne> <IsMale>false</IsMale> </PassResult> <TestResult> <

我有以下xml:

<?xml version="1.0" encoding="utf-8"?>
<RootData>
  <PassResult>
  <FirstOne>P1</FirstOne>
  <SecondOne>P2</SecondOne>
 <IsMale>false</IsMale>
</PassResult>
<TestResult>
  <MarkOne>100</MarkOne>
  <MarkTwo>50</MarkTwo>
  <Slope>30</Slope>
</TestResult>
<ToneTestResult>
  <TotalTime>2</TotalTime>
  <CorrectPercentage>90</CorrectPercentage>
</ToneTestResult>
<QuestionnaireResult Version="1">
  <Question Id="50">
   <Answer Id="B" />
 </Question>
  <Question Id="60">
   <Answer Id="A" />
 </Question>
 </QuestionnaireResult>
</RootData>

P1
P2
错误的
100
50
30
2.
90
我有下面的代码,看起来一点也不好。大量重复的链接查询。 如何以更结构化的方式重构此代码以填充“OutputData”对象。我现在不想将其更改为XmlSerializer:-(

示例代码:

    // Gets the root element decendants
        var elementRootData = xDocument.Descendants("RootData");

        var xElements = elementRootData as IList<XElement> ?? elementRootData.ToList();


   // Read first leaf node "ProfileResult"
        var passResult = from xElement in xElements.Descendants("PassResult")
            select new
            {

                FirstOne = xElement.Element("FirstOne").GetValue(),
                SecondOne = xElement.Element("SecondOne").GetValue(),
                IsMale = xElement.Element("IsMale").GetValue()
            };


    // Read second leaf note
        var testResult = from xElement in xElements.Descendants("TestResult")
            select new
            {

                MarkOne = xElement.Element("MarkOne").GetValue(),
                MarkTwo = xElement.Element("MarkTwo").GetValue(),
                Slope = xElement.Element("Slope").GetValue()
            };


    // Update OutputData object
        var parseOutputData = new OutputData();

    foreach (var result in passResult)
        {
            parseOutputData.FirstOne = result.FirstOne;
            parseOutputData.SecondOne = result.SecondOne;
            parseOutputData.IsMale = result.IsMale.Equals("True");
        }

        foreach (var result in testResult)
        {
            parseOutputData.MarkOne = double.Parse(result.MarkOne);
            parseOutputData.MarkTwo = double.Parse(result.MarkTwo);
            parseOutputData.Slope = double.Parse(result.Slope);
        }
//获取根元素decentants
var elementRootData=xDocument.subjects(“RootData”);
var xElements=elementRootData作为IList??elementRootData.ToList();
//读取第一个叶节点“ProfileResult”
var passResult=来自xElements.substands中的xElement(“passResult”)
选择新的
{
FirstOne=xElement.Element(“FirstOne”).GetValue(),
SecondOne=xElement.Element(“SecondOne”).GetValue(),
IsMale=xElement.Element(“IsMale”).GetValue()
};
//阅读第二页注释
var testResult=来自xElements.substands中的xElement(“testResult”)
选择新的
{
MarkOne=xElement.Element(“MarkOne”).GetValue(),
MarkTwo=xElement.Element(“MarkTwo”).GetValue(),
Slope=xElement.Element(“Slope”).GetValue()
};
//更新OutputData对象
var parseOutputData=新的OutputData();
foreach(passResult中的var结果)
{
parseOutputData.FirstOne=result.FirstOne;
parseOutputData.SecondOne=result.SecondOne;
parseOutputData.IsMale=result.IsMale.Equals(“True”);
}
foreach(testResult中的var结果)
{
parseOutputData.MarkOne=double.Parse(result.MarkOne);
parseOutputData.MarkTwo=double.Parse(result.MarkTwo);
parseOutputData.Slope=double.Parse(result.Slope);
}
我必须编写更多这样的代码来填充其他元素数据,如ToneTestResult、QuestionnaireResult等。 有人能提供一个示例代码吗


致以最诚挚的问候,

鉴于您的XML很小,您可能不必太担心性能。您可以利用内置的显式转换一次性完成全部工作:

var data = new OutputData
{
    FirstOne = (string) doc.Descendants("FirstOne").Single(),
    SecondOne = (string) doc.Descendants("SecondOne").Single(),
    IsMale = (bool) doc.Descendants("IsMale").Single(),
    MarkOne = (double) doc.Descendants("MarkOne").Single(),
    MarkTwo = (double) doc.Descendants("MarkTwo").Single(),
    Slope = (double) doc.Descendants("Slope").Single()
};
顺便说一句,
子体
永远不会返回任何实现
IList的内容,因此您可以明确地删除它。

试试XML Linq

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

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            var root = doc.Elements("RootData").Select(x => new
            {
                passResults = x.Elements("PassResult").Select(y => new
                {
                    firstOne = (string)y.Element("FirstOne"),
                    secondOne = (string)y.Element("SecondOne"),
                    isMale = (Boolean)y.Element("IsMale")
                }).FirstOrDefault(),
                testResult = x.Elements("TestResult").Select(y => new {
                    markOne = (int)y.Element("MarkOne"),
                    markTwo = (int)y.Element("MarkTwo"),
                    slope = (int)y.Element("Slope")
                }).FirstOrDefault(),
                toneTestResult = x.Elements("ToneTestResult").Select(y => new {
                    totalTime = (int)y.Element("TotalTime"),
                    correctPecentage = (int)y.Element("CorrectPercentage")
                }).FirstOrDefault(),
                questionnaireResult = x.Elements("QuestionnaireResult").Elements("Question").Select(y => new {
                    question = (int)y.Attribute("Id"),
                    answer = (string)y.Descendants("Answer").FirstOrDefault().Attribute("Id")
                }).ToList(),
            }).FirstOrDefault();

        }
    }
}

如果需要将整个xml转换为对象,为什么不反序列化xml?选项如下: