In C# I have a problem going through an complex XML document and get all the activity nodes with type="test-module" and result="Failed". So after that I would like to get the innterText from errormessage:
Here is my XML sample (short version):
<?xml version="1.0" encoding="utf-8"?>
<activity
result="Failed"
type="iteration-container"
datasource="DS_1">
<activity
result="Failed"
type="test-case"
testcontainername="TC_1"
iteration="1"
activity-exectype="dataiteration">
<datarow>
<field
name="Test">
TF 1.1
</field>
</datarow>
<activity
result="Failed"
type="test-module">
<errormessage>
Error Message
</errormessage>
</activity>
<activity
result="Success"
type="smart-folder">
<activity
result="Success"
type="test-module">
</activity>
</activity>
<activity
result="Success"
type="smart-folder">
<activity
result="Success"
type="smart-folder">
<activity
result="Success"
type="test-module">
</activity>
</activity>
</activity>
<activity
result="Failed"
type="smart-folder">
<activity
result="Failed"
type="smart-folder">
<activity
result="Failed"
type="test-module">
<errormessage>
Error Message
</errormessage>
</activity>
</activity>
</activity>
<activity
result="Failed"
type="smart-folder">
<activity
result="Failed"
type="test-module">
<errormessage>
Error Message
</errormessage>
</activity>
</activity>
</activity>
</activity>
Her is my code:
XmlDocument doc = new XmlDocument();
doc.Load("theXML.xml");
XmlElement root = doc.DocumentElement;
XmlNodeList dataSources = root.SelectNodes("//activity[@type='iteration-container']");
foreach(XmlNode dataSource in dataSources) {
XmlNodeList testCases = dataSource.SelectNodes("activity[@type='test-case']");
foreach(XmlNode testCase in testCases) {
if(testCase is XmlElement && dataSource is XmlElement) {
Report.Info("datasource: " + (dataSource as XmlElement).GetAttribute("datasource"));
Report.Info("result: " + (testCase as XmlElement).GetAttribute("result"));
Report.Info("testcontainername: " + (testCase as XmlElement).GetAttribute("testcontainername"));
Report.Info("iteration: " + (testCase as XmlElement).GetAttribute("iteration"));
Report.Info("Test: " + (testCase as XmlElement).SelectSingleNode("datarow/field[@name='Test']").InnerText.Trim());
if((testCase as XmlElement).GetAttribute("result").Equals("Failed")) {
XmlNodeList failedTestModules = testCase.SelectNodes("//activity[@type='test-module']"); //<= this code section doesnt work because it gets all failed test-modules for every node and I would like have failed test-modules for each test-case.
foreach(XmlNode faildTestModule in failedTestModules) {
if((faildTestModule as XmlElement).GetAttribute("result").Equals("Failed")) {
if(faildTestModule is XmlElement) {
Report.Info("Error Msg: " + (faildTestModule as XmlElement).SelectSingleNode("errormessage").InnerText.Trim());
}
}
}
}
Report.Info("---------------------------------------------------------------------------------------");
}
}
}
This code section doesnt work, because it gets all failed test-modules for every node.
XmlNodeList failedTestModules = testCase.SelectNodes("//activity[@type='test-module']");
I would like have failed test-modules
for each test-case
. Maybe someone have any suggestions?
In your xpath you need to specify you want navigate from current node (which is dot). Otherwise it would apply the xpath to the entire document.
XmlNodeList failedTestModules = testCase.SelectNodes(".//activity[@type='test-module']");