在反序列化期间获取任何深度的XMLElement

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在反序列化期间获取任何深度的XMLElement相关的知识,希望对你有一定的参考价值。

我是c#和XML反序列化的新手,请原谅我任何错误的单词/遗漏任何信息。

我使用根元素反序列化Nunit3测试结果XML作为测试运行,子元素是测试套件,然后是测试用例。

测试用例重复多次,具体取决于执行的测试用例的数量以及我感兴趣的元素。

Nunit XML的C#类如下所示。

[XmlRoot(ElementName = "test-run")]
public class Testrun
{
    [XmlElement(ElementName = "command-line")]
    public string Commandline { get; set; }
    [XmlElement(ElementName = "test-suite")]
    public Testsuite Testsuite { get; set; }
}

[XmlRoot(ElementName = "test-suite")]
public class Testsuite
{
[XmlElement(ElementName = "test-case")]
    public Testcase Testcase { get; set; }
}

但有时嵌套的测试套件元素会出现在Nunit XML中,如下所示。

<test-suite type="TestSuite" id="0-1005" name="TopGearFramework" fullname="TopGearFramework" runstate="Runnable" testcasecount="2" result="Failed" site="Child" start-time="2019-02-21 04:17:28Z" end-time="2019-02-21 04:19:16Z" duration="108.354384" total="2" passed="1" failed="1" warnings="0" inconclusive="0" skipped="0" asserts="14">
  <test-suite type="TestSuite" id="0-1006" name="CFTestCases" fullname="TopGearFramework.CFTestCases" runstate="Runnable" testcasecount="2" result="Failed" site="Child" start-time="2019-02-21 04:17:28Z" end-time="2019-02-21 04:19:16Z" duration="108.353019" total="2" passed="1" failed="1" warnings="0" inconclusive="0" skipped="0" asserts="14">
      <test-suite type="TestSuite" id="0-1007" name="PoCTestCases" fullname="TopGearFramework.CFTestCases.PoCTestCases" runstate="Runnable" testcasecount="2" result="Failed" site="Child" start-time="2019-02-21 04:17:28Z" end-time="2019-02-21 04:19:16Z" duration="108.352989" total="2" passed="1" failed="1" warnings="0" inconclusive="0" skipped="0" asserts="14">
        <test-suite type="TestSuite" id="0-1008" name="FeatureFiles" fullname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles" runstate="Runnable" testcasecount="2" result="Failed" site="Child" start-time="2019-02-21 04:17:28Z" end-time="2019-02-21 04:19:16Z" duration="108.352968" total="2" passed="1" failed="1" warnings="0" inconclusive="0" skipped="0" asserts="14">
           <test-suite type="TestFixture" id="0-1002" name="IndividualDealerPartyCreationFeature" fullname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles.IndividualDealerPartyCreationFeature" classname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles.IndividualDealerPartyCreationFeature" runstate="Runnable" testcasecount="1" result="Passed" start-time="2019-02-21 04:17:28Z" end-time="2019-02-21 04:19:07Z" duration="99.414157" total="1" passed="1" failed="0" warnings="0" inconclusive="0" skipped="0" asserts="10">
                  <test-case id="0-1003" name="XF_PAM_004_CheckNewDealerPartyCreationForIndividual" fullname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles.IndividualDealerPartyCreationFeature.XF_PAM_004_CheckNewDealerPartyCreationForIndividual" methodname="XF_PAM_004_CheckNewDealerPartyCreationForIndividual" classname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles.IndividualDealerPartyCreationFeature" runstate="Runnable" seed="293675085" result="Passed" start-time="2019-02-21 04:17:29Z" end-time="2019-02-21 04:19:07Z" duration="98.585096" asserts="10">

请注意,在测试用例发生之前,测试套件重复5次。在反序列化期间,我对测试用例对象变为null。

如何处理测试套件元素的动态嵌套或重复以获得测试用例?

提前致谢。

编辑1#完整XML复制以供参考。

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<test-run id="2" testcasecount="2" result="Failed" total="2" passed="1" failed="1" inconclusive="0" skipped="0" asserts="14" engine-version="3.9.0.0" clr-version="4.0.30319.42000" start-time="2019-02-21 04:17:25Z" end-time="2019-02-21 04:19:16Z" duration="111.183778">
  <command-line><![CDATA["C:Program Files (x86)NUnit.org
unit-console
unit3-console.exe"   TopGearFrameworkinDebugTopGearFramework.dll --result=TestResult.xml --labels=All --out=TestResult.txt]]></command-line>
  <test-suite type="Assembly" id="0-1004" name="TopGearFramework.dll" fullname="TopGearFramework.dll" runstate="Runnable" testcasecount="2" result="Failed" site="Child" start-time="2019-02-21 04:17:28Z" end-time="2019-02-21 04:19:16Z" duration="108.409138" total="2" passed="1" failed="1" warnings="0" inconclusive="0" skipped="0" asserts="14">
    <environment framework-version="3.11.0.0" clr-version="4.0.30319.42000" os-version="Microsoft Windows NT 10.0.16299.0" platform="Win32NT" cwd="C:Usersqxm5789.jenkinsworkspaceTopGearTestRunner_master" machine-name="VMUC0034748" user="qxm5789" user-domain="MUC" culture="en-US" uiculture="en-US" os-architecture="x64" />
    <settings>
      <setting name="DisposeRunners" value="True" />
    </settings>
    <properties>
      <property name="_PID" value="1852" />
      <property name="_APPDOMAIN" value="domain-" />
    </properties>
    <failure>
      <message><![CDATA[One or more child tests had errors]]></message>
    </failure>
    <test-suite type="TestSuite" id="0-1005" name="TopGearFramework" fullname="TopGearFramework" runstate="Runnable" testcasecount="2" result="Failed" site="Child" start-time="2019-02-21 04:17:28Z" end-time="2019-02-21 04:19:16Z" duration="108.354384" total="2" passed="1" failed="1" warnings="0" inconclusive="0" skipped="0" asserts="14">
      <failure>
        <message><![CDATA[One or more child tests had errors]]></message>
      </failure>
      <test-suite type="TestSuite" id="0-1006" name="CFTestCases" fullname="TopGearFramework.CFTestCases" runstate="Runnable" testcasecount="2" result="Failed" site="Child" start-time="2019-02-21 04:17:28Z" end-time="2019-02-21 04:19:16Z" duration="108.353019" total="2" passed="1" failed="1" warnings="0" inconclusive="0" skipped="0" asserts="14">
        <failure>
          <message><![CDATA[One or more child tests had errors]]></message>
        </failure>
        <test-suite type="TestSuite" id="0-1007" name="PoCTestCases" fullname="TopGearFramework.CFTestCases.PoCTestCases" runstate="Runnable" testcasecount="2" result="Failed" site="Child" start-time="2019-02-21 04:17:28Z" end-time="2019-02-21 04:19:16Z" duration="108.352989" total="2" passed="1" failed="1" warnings="0" inconclusive="0" skipped="0" asserts="14">
          <failure>
            <message><![CDATA[One or more child tests had errors]]></message>
          </failure>
          <test-suite type="TestSuite" id="0-1008" name="FeatureFiles" fullname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles" runstate="Runnable" testcasecount="2" result="Failed" site="Child" start-time="2019-02-21 04:17:28Z" end-time="2019-02-21 04:19:16Z" duration="108.352968" total="2" passed="1" failed="1" warnings="0" inconclusive="0" skipped="0" asserts="14">
            <failure>
              <message><![CDATA[One or more child tests had errors]]></message>
            </failure>
            <test-suite type="TestFixture" id="0-1002" name="IndividualDealerPartyCreationFeature" fullname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles.IndividualDealerPartyCreationFeature" classname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles.IndividualDealerPartyCreationFeature" runstate="Runnable" testcasecount="1" result="Passed" start-time="2019-02-21 04:17:28Z" end-time="2019-02-21 04:19:07Z" duration="99.414157" total="1" passed="1" failed="0" warnings="0" inconclusive="0" skipped="0" asserts="10">
              <properties>
                <property name="Description" value="Individual Dealer Party Creation" />
              </properties>
              <output><![CDATA[-> Using app.config
]]></output>
              <test-case id="0-1003" name="XF_PAM_004_CheckNewDealerPartyCreationForIndividual" fullname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles.IndividualDealerPartyCreationFeature.XF_PAM_004_CheckNewDealerPartyCreationForIndividual" methodname="XF_PAM_004_CheckNewDealerPartyCreationForIndividual" classname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles.IndividualDealerPartyCreationFeature" runstate="Runnable" seed="293675085" result="Passed" start-time="2019-02-21 04:17:29Z" end-time="2019-02-21 04:19:07Z" duration="98.585096" asserts="10">
                <properties>
                  <property name="Description" value="XF_PAM_004_Check New Dealer Party Creation for Individual" />

                </properties>
                <output><![CDATA[Given Browser is launched
-> done: IndividualDealerPartyCreationSteps.GivenBrowserIsLaunched() (0.0s)
]]></output>
                <attachments>
                  <attachment>
                    <filePath>C:Usersqxm5789.jenkinsworkspaceTopGearTestRunner_masterTestResultsXF_PAM_004_Check New Dealer Party Creation for Individual2019-02-21-11_19_02.jpg</filePath>
                    <description><![CDATA[Screenshot captured]]></description>
                  </attachment>
                </attachments>
              </test-case>
            </test-suite>
            <test-suite type="TestFixture" id="0-1000" name="TestOriginationAPIFeature" fullname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles.TestOriginationAPIFeature" classname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles.TestOriginationAPIFeature" runstate="Runnable" testcasecount="1" result="Failed" site="Child" start-time="2019-02-21 04:19:07Z" end-time="2019-02-21 04:19:16Z" duration="8.923635" total="1" passed="0" failed="1" warnings="0" inconclusive="0" skipped="0" asserts="4">
              <properties>
                <property name="Description" value="Test Origination API" />
              </properties>
              <failure>
                <message><![CDATA[One or more child tests had errors]]></message>
              </failure>
              <test-case id="0-1001" name="FE_AHA_040_SearchApplicationByApplicationIDThroughOriginationAPI" fullname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles.TestOriginationAPIFeature.FE_AHA_040_SearchApplicationByApplicationIDThroughOriginationAPI" methodname="FE_AHA_040_SearchApplicationByApplicationIDThroughOriginationAPI" classname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles.TestOriginationAPIFeature" runstate="Runnable" seed="2107869277" result="Failed" start-time="2019-02-21 04:19:07Z" end-time="2019-02-21 04:19:16Z" duration="8.921560" asserts="4">
                <properties>
                  <property name="Description" value="FE_AHA_040_Search Application By Application ID through Origination API" />

                </properties>
                <failure>
                  <message><![CDATA[  Error Occured: 
  Expected: <empty>
  But was:  < "Contract ID 12345 not found." >
]]></message>
                  <stack-trace><![CDATA[   
]]></stack-trace>
                </failure>
                <output><![CDATA[
]]></output>
                <assertions>
                  <assertion result="Failed">
                    <message><![CDATA[  Error Occured: 
  Expected: <empty>
  But was:  < "Contract ID 12345 not found." >
]]></message>
                    <stack-trace><![CDATA[   
]]></stack-trace>
                  </assertion>
                </assertions>
              </test-case>
            </test-suite>
          </test-suite>
        </test-suite>
      </test-suite>
    </test-suite>
  </test-suite>
</test-run>
答案

如果你想用XML获取任何深度的所有<test-case>节点,那么XDocument.Descendants("test-case")会为你做这个。

通过使用LINQ,您可以从每个result节点检索属性<test-case>,如果message节点内存在<failure>节点,则可以从<test-case>节点检索class Program { public static void Main(string[] args) { XDocument doc = XDocument.Load(@"Path to your xml file"); var result = (from t in doc.Descendants("test-case") from f in t.Descendants("failure") select new { Result = t.Attribute("result").Value, Failure_Message = f.Element("message") != null ? f.Element("message").Value : "" }).ToList(); //---------------Print the result------------------ foreach (var item in result) { Console.WriteLine("Result: " + item.Result); Console.WriteLine("Message: " + item.Failure_Message); } Console.ReadLine(); }

然后下面的代码为您提供结果的失败消息列表。

enter image description here

输出:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; using System.Xml; using System.Xml.Linq; namespace ConsoleApplication100 { class Program { const string FILENAME = @"c: emp est.xml"; static void Main(string[] args) { XDocument doc = XDocument.Load(FILENAME); Testrun testrun = new Testrun(); testrun.ParseXml(FILENAME); } } public class Testrun { public string Commandline { get; set; } public Testsuite Testsuite { get; set; } public void ParseXml(string filename) { XDocument doc = XDocument.Load(filename); XElement Testrun = doc.Root; Commandline = (string)Testrun.Element("command-line"); XElement testsuit = Testrun.Element("test-suite"); if (testsuit != null) { Testsuite = new Testsuite(testsuit); } } } public class Testsuite { public Attributes attributes { get; set; } public Testsuite testsuite { get; set; } public string failure_message { get; set; } public string property_name { get; set; } public string property_value { get; set; } public TestCase TestCase { get; set; } public Testsuite(XElement xTestsuite) { attributes = new Attributes(xTestsuite); XElement failure = xTestsuite.Element("failure"); if (failure != null) failure_message = (string)failure.Element("message"); XElement properties = xTestsuite.Element("properties"); if (properties != null) { XElement property = properties.Element("property"); property_name = (string)property.Attribute("name"); property_value = (string)property.Attribute("value"); } XElement testcase = xTestsuite.Element("test-case"); if (testcase != null) { TestCase = new TestCase(testcase); } xTestsuite = xTestsuite.Element("test-suite"); if (xTestsuite != null) { testsuite = new Testsuite(xTestsuite); } } } public class TestCase { public string output { get; set; } public string property_name { get; set; } public string property_value { get; set; } public string attachment_filePath { get; set; } public string attachment_description { get; set; } public TestCase(XElement testCase) { XElement xOutput = testCase.Element("output"); if (xOutput != null) output = (string)xOutput; XElement properties = testCase.Element("properties"); if (properties != null) { XElement property = properties.Element("property"); property_name = (string)property.Attribute("name"); property_value = (string)property.Attribute("value"); } XElement attachments = testCase.Element("attachments"); if (attachments != null) { XElement attachment = attachments.Element("attachment"); attachment_filePath = (string)attachment.Element("filePath"); attachment_description = (string)attachment.Element ("description"); } } } public class Attributes { string testtype { get; set; } string id { get; set; } string name { get; set; } string fullname { get; set; } string runstate { get; set; } int testcasecount { get; set; } string result { get; set; } string site { get; set; } DateTime start_time { get; set; } DateTime end_time { get; set; } decimal duration { get; set; } int total { get; set; } int passed { get; set; } int failed { get; set; } int warnings { get; set; } int inconclusive { get; set; } int skipped { get; set; } int asserts { get; set; } public Attributes(XElement attributes) { testtype = (string)attributes.Attribute("type"); id = (string)attributes.Attribute("id"); name = (string)attributes.Attribute("name"); fullname = (string)attributes.Attribute("fullname"); runstate = (string)attributes.Attribute("runstate"); testcasecount = (int)attributes.Attribute("testcasecount"); result = (string)attributes.Attribute("result"); site = (string)attributes.Attribute("site"); start_time = (DateTime)attributes.Attribute("start-time"); end_time = (DateTime)attributes.Attribute("end-time"); duration = (decimal)attributes.Attribute("duration"); total = (int)attributes.Attribute("total"); passed = (int)attributes.Attribute("passed"); failed = (int)attributes.Attribute("failed"); warnings = (int)attributes.Attribute("warnings"); inconclusive = (int)attributes.Attribute("inconclusive"); skipped = (int)attributes.Attribute("skipped"); asserts = (int)attributes.Attribute("asserts"); } } }

另一答案

您需要一个自定义解析器。我使用xml linq:

qazxswpoi

以上是关于在反序列化期间获取任何深度的XMLElement的主要内容,如果未能解决你的问题,请参考以下文章

在反序列化期间使用 XML 装饰指定默认值

ProtoBuf 在反序列化期间损坏字节数组(添加了额外的 0)

用于在反序列化期间忽略未知属性的 SpringMVC 全局设置

JsonSerializer 在反序列化期间不使用内部构造函数

在反序列化期间将 JSON 日期转换为 .NET DateTime 的正确方法

Jersey 2.8客户端在反序列化期间没有忽略未知属性