def matchNode()

in verifiers/xmlElementMatch.py [0:0]


    def matchNode(cls, root, xpath, parent_map=None, title=None):

        if title is None:
            title = xpath
        result = True
        resulttxt = ""

        # Find the first test in the xpath
        if '[' in xpath:
            actual_xpath, tests = xpath.split('[', 1)
        else:
            actual_xpath = xpath
            tests = None

        if parent_map is None:
            parent_map = dict((c, p) for p in root.getiterator() for c in p)

        # Handle parents
        if actual_xpath.startswith("../"):
            root = parent_map[root]
            actual_xpath = "./" + actual_xpath[3:]

        # Handle absolute root element and find all matching nodes
        r = re.search("(/?\{[^\}]+\}[^/]+|\.)(.*)", actual_xpath)
        if r.group(2):
            root_path = r.group(1)
            child_path = r.group(2)[1:]
            if root_path != "." and root.tag != root_path.lstrip("/"):
                resulttxt += "        Items not returned in XML for %s\n" % (title,)
                result = False
                return result, resulttxt
            nodes = root.findall(child_path)
        else:
            nodes = (root,)

        if len(nodes) == 0:
            resulttxt += "        Items not returned in XML for %s\n" % (title,)
            result = False
            return result, resulttxt

        if tests:
            # Split the tests into tests plus additional path
            pos = tests.find("]/")
            if pos != -1:
                node_tests = tests[:pos + 1]
                next_path = tests[pos + 1:]
            else:
                node_tests = tests
                next_path = None

            node_tests = [item[:-1] for item in node_tests.split('[')]
            for test in node_tests:
                for node in nodes:
                    testresult = cls.testNode(node, title, test)
                    if testresult is None:
                        if next_path:
                            next_result, testresult = cls.matchNode(node, next_path[1:], parent_map, title)
                            if next_result:
                                break
                        else:
                            break

                if testresult:
                    resulttxt += testresult
                    result = False
                    break

        return result, resulttxt