xml 解析 - 代码重构问题

xml parsing - code refactoring issue

我有以下 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>

我有以下代码,看起来一点也不好。大量重复 link 查询。 如何以更有条理的方式重构此代码以填充 "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);
        }

我必须编写更多这样的代码来填充其他元素数据,如 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()
};

顺便说一句,Descendants 永远不会 return 任何实现 IList<XElement> 的东西,所以你绝对可以删除它。

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

        }
    }
}