使用 XElement 解析 XUnit XML 文件中的多个元素时出现问题

Problem parsing through multiple elements in the XUnit XML file using XElement

我在使用 XElement 通过 XUnit XML 文件和 return 值解析多个元素时遇到问题。

这是 XML 文件

<assemblies timestamp="07/31/2018 14:58:48">
  <assembly name="C:\Users\bf\Documents\Visual Studio 2015\Projects\xUnitDemo\xUnitDemo\bin\Debug\xUnitDemo.DLL" environment="64-bit .NET 4.0.30319.42000 [collection-per-class, parallel (1 threads)]" test-framework="xUnit.net 2.3.1.3858" run-date="2018-07-31" run-time="14:58:47" config-file="C:\Users\bf\Documents\Visual Studio 2015\Projects\xUnitDemo\packages\xunit.runner.console.2.4.0\tools\net452\xunit.console.exe.Config" total="15" passed="14" failed="1" skipped="0" time="0.257" errors="0">
    <errors />
    <collection total="2" passed="1" failed="1" skipped="0" name="Test collection for xUnitDemo.SimpleTests" time="0.070">
      <test name="xUnitDemo.SimpleTests.PassingTest" type="xUnitDemo.SimpleTests" method="PassingTest" time="0.0636741" result="Pass">
        <traits>
          <trait name="test" value="test" />
          <trait name="requirement" value="test" />
          <trait name="labels" value="test" />
        </traits>
      </test>
      <test name="xUnitDemo.SimpleTests.FailingTest" type="xUnitDemo.SimpleTests" method="FailingTest" time="0.0059474" result="Fail">
        <failure exception-type="Xunit.Sdk.EqualException">
          <message><![CDATA[Assert.Equal() Failure\r\nExpected: 5\r\nActual: 4]]></message>
          <stack-trace><![CDATA[ at xUnitDemo.SimpleTests.FailingTest() in C:\Users\smsf\documents\visual studio 2015\Projects\xUnitDemo\xUnitDemo\SimpleTests.cs:line 30]]></stack-trace>
        </failure>
      </test>
    </collection>
  </assembly>
</assemblies>

我可以使用此代码解析 test 元素。

private static List<TestResults> GetTestAutomationExecutionResult(string filePath)
{
    List<TestResults> testResults = new List<TestResults>();

    XElement xelement = XElement.Load(filePath);

    IEnumerable<XElement> results = xelement.Elements().Where(e => e.Name.LocalName == "test");
    
    foreach (var result in results)
    {
        if (result.Attribute("result").Value == "Fail")
        {
            testResults.Add(new TestResults(result.Attribute("result").Value, "this is where the failure message would go"));
        }
        else
        {
            testResults.Add(new TestResults(result.Attribute("result").Value, ""));
        }
    }

但我很难在 foreach 的 failure 元素中查找和添加消息。

 result.Attribute("message").Value

您的代码有几个问题:

  1. <result> 元素不是根元素的直接子元素,因此 xelement.Elements().Where(e => e.Name.LocalName == "test") 没有 select 任何东西。您需要深入到层次结构中,例如Descendants().

  2. 消息文本包含在 <test> 节点的间接子元素中,特别是 failure/message。您需要 select 此元素才能获取消息。

    result.Attribute("message").Value 将不起作用,因为 XElement.Attribute(XName) method selects an XML attribute rather than an element.

    参见:XML attribute vs XML element

将这两点放在一起,您的代码应该如下所示:

private static List<TestResults> GetTestAutomationExecutionResult(string filePath)
    => GetTestAutomationExecutionResult(XElement.Load(filePath));

private static List<TestResults> GetTestAutomationExecutionResult(XElement xelement)
{
    var query = from e in xelement.Descendants()
        where e.Name.LocalName == "test"
        let r = e.Attribute("result").Value
        let m = r == "Fail" ? e.Elements("failure").Elements("message").FirstOrDefault()?.Value : ""
        select new TestResults(r, m);
    return query.ToList();
}

演示 fiddle here.