【问题标题】:xml parsing - code refactoring issuexml 解析 - 代码重构问题
【发布时间】:2016-06-06 13:57:05
【问题描述】:

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

我有以下代码,看起来一点也不好看。大量重复的链接查询。 如何以更结构化的方式重构此代码以填充“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 等。 有人可以提供示例代码吗?

最好的问候,

【问题讨论】:

标签: c# xml linq-to-xml xelement


【解决方案1】:

鉴于您的 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 永远不会返回任何实现IList&lt;XElement&gt; 的东西,所以你绝对可以删除它。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-01
      • 1970-01-01
      相关资源
      最近更新 更多