如何从复杂的 XML 文档结构中获取指定的节点值

How to get specified Node values from complex XML document structure

在 C# 中,我在处理复杂的 XML 文档并获取类型为“test-module”和结果为“Failed”的所有 activity 节点时遇到了问题。所以在那之后我想从错误消息中获取 innterText:

这是我的 XML 示例(简短版):

<?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>

她是我的密码:

        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("---------------------------------------------------------------------------------------");
                }
            }
        }

此代码部分不起作用,因为它获取每个节点的所有失败测试模块。

XmlNodeList failedTestModules = testCase.SelectNodes("//activity[@type='test-module']"); 

我希望每个 test-case 都失败 test-modules。也许有人有什么建议?

在您的 xpath 中,您需要指定要从当前节点(点)导航。否则它会将 xpath 应用于整个文档。

XmlNodeList failedTestModules = testCase.SelectNodes(".//activity[@type='test-module']");