From 2cf62c5eba91866e7de828d9c5084aa3f21d4ba0 Mon Sep 17 00:00:00 2001 From: Lennart Regebro Date: Tue, 18 Sep 2018 09:12:19 +0200 Subject: [PATCH] See if we can get a better codeclimate score. (Probably not) --- xmldiff/diff.py | 14 ++++++++------ xmldiff/formatting.py | 10 ++++++++++ xmldiff/main.py | 22 ++++++++++++---------- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/xmldiff/diff.py b/xmldiff/diff.py index 2585afa..cdef113 100644 --- a/xmldiff/diff.py +++ b/xmldiff/diff.py @@ -298,13 +298,15 @@ def find_pos(self, child): break return i + def _get_matched_children(self, this, other, mapping): + return [child for child in this.getchildren() + if id(child) in mapping and + mapping[id(child)].getparent() is other] + def align_children(self, left, right): - lchildren = [c for c in left.getchildren() - if (id(c) in self._l2rmap and - self._l2rmap[id(c)].getparent() is right)] - rchildren = [c for c in right.getchildren() - if (id(c) in self._r2lmap and - self._r2lmap[id(c)].getparent() is left)] + lchildren = self._get_matched_children(left, right, self._l2rmap) + rchildren = self._get_matched_children(right, left, self._r2lmap) + if not lchildren or not rchildren: # Nothing to align return diff --git a/xmldiff/formatting.py b/xmldiff/formatting.py index 9752b20..a6f3e53 100644 --- a/xmldiff/formatting.py +++ b/xmldiff/formatting.py @@ -360,41 +360,51 @@ def _xpath(self, node, xpath): # one and exactly one element is found. This is to protect against # formatting a diff on the wrong tree, or against using ambigous # edit script xpaths. + + # Check if this path is absolute (start with root) if xpath[0] == '/': root = True xpath = xpath[1:] else: root = False + # Find the first item in the path if '/' in xpath: path, rest = xpath.split('/', 1) else: path = xpath rest = '' + # Get the items index if '[' in path: path, index = path[:-1].split('[') index = int(index) - 1 multiple = False else: + # If the path doesn't have an index, then [1] is implied index = 0 multiple = True if root: + # Now add back the starting /, if there was one path = '/' + path + # Find the nodes that match matches = [] for match in node.xpath(path, namespaces=node.nsmap): # Skip nodes that have been deleted if DELETE_NAME not in match.attrib: matches.append(match) + # Get the node specified from the matches if index >= len(matches): raise ValueError('xpath %s[%s] not found at %s.' % ( path, index + 1, utils.getpath(node))) if len(matches) > 1 and multiple: raise ValueError('Multiple nodes found for xpath %s at %s.' % ( path, utils.getpath(node))) + + # Found it! match = matches[index] if rest: return self._xpath(match, rest) diff --git a/xmldiff/main.py b/xmldiff/main.py index 4e290cf..530ced4 100644 --- a/xmldiff/main.py +++ b/xmldiff/main.py @@ -27,24 +27,26 @@ def diff_trees(left, right, F=None, uniqueattrs=None, formatter=None): return formatter.format(diffs, left) -def diff_texts(left, right, F=None, uniqueattrs=None, formatter=None): - """Takes two Unicode strings containing XML""" +def _parse_and_diff(tree_maker, left, right, F=None, uniqueattrs=None, + formatter=None): normalize = bool(getattr(formatter, 'normalize', 1) & formatting.WS_TAGS) parser = etree.XMLParser(remove_blank_text=normalize) - left_tree = etree.fromstring(left, parser) - right_tree = etree.fromstring(right, parser) + left_tree = tree_maker(left, parser) + right_tree = tree_maker(right, parser) return diff_trees(left_tree, right_tree, F=F, uniqueattrs=uniqueattrs, formatter=formatter) +def diff_texts(left, right, F=None, uniqueattrs=None, formatter=None): + """Takes two Unicode strings containing XML""" + return _parse_and_diff(etree.fromstring, left, right, F, + uniqueattrs, formatter) + + def diff_files(left, right, F=None, uniqueattrs=None, formatter=None): """Takes two filenames or streams, and diffs the XML in those files""" - normalize = bool(getattr(formatter, 'normalize', 1) & formatting.WS_TAGS) - parser = etree.XMLParser(remove_blank_text=normalize) - left_tree = etree.parse(left, parser) - right_tree = etree.parse(right, parser) - return diff_trees(left_tree, right_tree, F=F, uniqueattrs=uniqueattrs, - formatter=formatter) + return _parse_and_diff(etree.parse, left, right, F, + uniqueattrs, formatter) def make_parser():