2016-08-05 111 views
-2

我無法讓我的Xpath查詢工作,儘管在紙上它應該是正確的。我甚至試圖讓無屬性的單節點,甚至無法得到這個...C#XML XPath查詢不起作用

我在做什麼錯?

Built result trx (cml) format

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

http://stackoverflow.com/documentation/xpath/2324/namespaces#t=201608050604347342848 –

回答

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(); 
+0

感謝您的答覆的細節和清晰度。因爲GetElementsByTagName(「UnitTestResult」)工作,我錯誤地認爲不需要命名空間。 –