c# - 在反序列化期间获取任意深度的 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\nunit-console\nunit3-console.exe" TopGearFramework\bin\Debug\TopGearFramework.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:\Users\qxm5789\.jenkins\workspace\TopGearTestRunner_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:\Users\qxm5789\.jenkins\workspace\TopGearTestRunner_master\TestResults\\XF_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>
解决方案
如果您想<test-case>
在 XML 中获取任何深度的所有节点,那么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();
}
输出:
推荐阅读
- python - 如何使用 bs4 正确解析谷歌搜索结果?
- java - Apache骆驼将URI路由到另一个URI
- javascript - 如何在 Node.js 的客户端使用 ES6 类
- tensorboard - 如何用张量板批量写入?
- python - Python bdist_wheel + install 有效,但由于 PEP 517 sdist + install 失败
- java - 删除Horizontal RecyclerView java中项目之间的空格
- css - Bootstrap 如何导入我的自定义变量而不是可怕地增加编译时间?
- javascript - 为什么动画回调会扰乱我组件的生命周期?
- arrays - 用 C 语言反转句子,单词之间只有一个空格字符
- python - Pyyaml 条件语句