我不能让我的Xpath查询工作,虽然在纸上它应该是正确的。我甚至试图获得没有属性的单个节点,甚至无法得到这个......
我做错了什么?
var trxXml = new XmlDocument();
trxXml.Load(InputTrxFile);
XmlElement root = trxXml.DocumentElement;
var unitTestResult = trxXml.GetElementsByTagName("UnitTestResult");
foreach (XmlElement runinfo in unitTestResult)
{
// Find failed tests, works fine then...
string TestName = runinfo.GetAttribute("testName"); // works fine
// Want to find equivalent TestDefinitions/UnitTest
/* Tried
TestRun/TestDefinitions/UnitTest[@name='thetest']
/TestRun/TestDefinitions/UnitTest[@name='thetest']
TestDefinitions/UnitTest[@name='thetest']
/TestDefinitions/UnitTest[@name='thetest']
UnitTest[@name='thetest']
variations with no attribute test JUST to get a node
Example http://www.csharp-examples.net/xml-nodes-by-attribute-value/
*/
var xpath = string.Format(@"/TestRun/TestDefinitions/UnitTest[@name='{0}']", TestName);
XmlNode node = trxXml.SelectSingleNode(xpath);
XmlNode node2 = root.SelectSingleNode(xpath);
// These all return null
答案 0 :(得分:1)
任何以/
开头的查询都代表绝对路径,即它来自文档的根。您的UnitTestResult
元素(至少)似乎包含了您的TestRun
元素。
要让您的查询考虑当前上下文,您需要引用当前上下文。可以使用.
选择此内容。
其次,您的XML元素都有命名空间,这需要构成您查询的一部分。需要将前缀添加到命名空间管理器中,在查询中使用,并将管理器传递给查询方法。
因此,将这些结合起来,定义前缀:
var manager = new XmlNamespaceManager(new NameTable());
manager.AddNamespace("t", "http://microsoft.com/schemas/VisualStudio/TeamTest/2010");
更改您的查询:
./t:TestRun/t:TestDefinitions/t:UnitTest[@name='{0}']
并将命名空间管理器传递给方法:
trxXml.SelectSingleNode(xpath, manager);
但是,XPath和XmlDocument
很痛苦。在LINQ to XML中,这一切都会更直接:
var doc = XDocument.Load(InputTrxFile);
var unitTestQuery =
from result in doc.Descendants(ns + "UnitTestResult")
let name = (string)result.Attribute("testName")
from unitTest in result.Descendants(ns + "UnitTest")
where (string)unitTest.Attribute("name") == name
select unitTest;
var unitTest = unitTestQuery.Single();