<PackageReference Include="NUnit" Version="3.0.0-alpha-5" />

XmlNode

public class XmlNode
XmlNode represents a single node in the XML representation of a Test or TestResult. It replaces System.Xml.XmlNode and provides a minimal set of methods for operating on the XML in a platform-independent manner.
using System; using System.IO; using System.Xml; namespace NUnit.Framework.Interfaces { public class XmlNode { private class NodeFilter { private string nodeName; private string propName; private string propValue; public NodeFilter(string xpath) { nodeName = xpath; int num = xpath.IndexOf('['); if (num >= 0) { if (!xpath.EndsWith("]")) throw new ArgumentException("Invalid property expression", "xpath"); nodeName = xpath.Substring(0, num); string text = xpath.Substring(num + 1, xpath.Length - num - 2); int num2 = text.IndexOf('='); if (num2 < 0 || text[0] != '@') throw new ArgumentException("Invalid property expression", "xpath"); propName = text.Substring(1, num2 - 1).Trim(); propValue = text.Substring(num2 + 1).Trim(' ', '"', '\''); } } public bool Pass(XmlNode node) { if (node.Name != nodeName) return false; if (propName == null) return true; return node.Attributes[propName] == propValue; } } private string name; private AttributeDictionary attributes; private NodeList childNodes; private string textContent; public string Name => name; public string TextContent { get { return textContent; } set { textContent = value; } } public string EscapedTextContent => Escape(textContent); public AttributeDictionary Attributes => attributes; public NodeList ChildNodes => childNodes; public XmlNode FirstChild { get { if (ChildNodes.Count <= 0) return null; return ChildNodes[0]; } } public string OuterXml { get { StringWriter stringWriter = new StringWriter(); XmlWriterSettings xmlWriterSettings = new XmlWriterSettings(); xmlWriterSettings.ConformanceLevel = ConformanceLevel.Fragment; using (XmlWriter writer = XmlWriter.Create(stringWriter, xmlWriterSettings)) WriteTo(writer); return stringWriter.ToString(); } } public XmlNode(string name) { this.name = name; attributes = new AttributeDictionary(); childNodes = new NodeList(); } public static XmlNode CreateTopLevelElement(string name) { return new XmlNode(name); } public XmlNode AddElement(string name) { XmlNode xmlNode = new XmlNode(name); ChildNodes.Add(xmlNode); return xmlNode; } public void AddAttribute(string name, string value) { Attributes.Add(name, value); } public XmlNode FindDescendant(string xpath) { NodeList nodeList = FindDescendants(xpath); if (nodeList.Count <= 0) return null; return nodeList[0]; } public NodeList FindDescendants(string xpath) { NodeList nodeList = new NodeList(); nodeList.Add(this); return ApplySelection(nodeList, xpath); } public void WriteTo(XmlWriter writer) { writer.WriteStartElement(Name); foreach (string key in Attributes.Keys) { writer.WriteAttributeString(key, Attributes[key]); } if (TextContent != null) writer.WriteString(TextContent); foreach (XmlNode childNode in ChildNodes) { childNode.WriteTo(writer); } writer.WriteEndElement(); } private static NodeList ApplySelection(NodeList nodeList, string xpath) { Guard.ArgumentNotNullOrEmpty(xpath, "xpath"); if (xpath[0] == '/') throw new ArgumentException("XPath expressions starting with '/' are not supported", "xpath"); if (xpath.IndexOf("//") >= 0) throw new ArgumentException("XPath expressions with '//' are not supported", "xpath"); string xpath2 = xpath; string text = null; int num = xpath.IndexOf('/'); if (num >= 0) { xpath2 = xpath.Substring(0, num); text = xpath.Substring(num + 1); } NodeList nodeList2 = new NodeList(); NodeFilter nodeFilter = new NodeFilter(xpath2); foreach (XmlNode node in nodeList) { foreach (XmlNode childNode in node.ChildNodes) { if (nodeFilter.Pass(childNode)) nodeList2.Add(childNode); } } if (text == null) return nodeList2; return ApplySelection(nodeList2, text); } private static string Escape(string original) { return original.Replace("&", "&amp;").Replace("\"", "&quot;").Replace("'", "&apos;") .Replace("<", "&lt;") .Replace(">", "&gt;"); } } }