Merge xml files with nested elements without external libraries

前端 未结 3 1850
庸人自扰
庸人自扰 2020-12-02 19:42

I am trying to merge multiple XML files together using Python and no external libraries. The XML files have nested elements.

Sample File 1:

3条回答
  •  無奈伤痛
    2020-12-02 19:48

    Thank you, but my problem was to merge by considering the attributes also. here is the code after my patch:

        import sys
        from xml.etree import ElementTree as et
    
    
        class hashabledict(dict):
            def __hash__(self):
                return hash(tuple(sorted(self.items())))
    
    
        class XMLCombiner(object):
            def __init__(self, filenames):
                assert len(filenames) > 0, 'No filenames!'
                # save all the roots, in order, to be processed later
                self.roots = [et.parse(f).getroot() for f in filenames]
    
        def combine(self):
            for r in self.roots[1:]:
                # combine each element with the first one, and update that
                self.combine_element(self.roots[0], r)
            # return the string representation
            return et.ElementTree(self.roots[0])
    
        def combine_element(self, one, other):
            """
            This function recursively updates either the text or the children
            of an element if another element is found in `one`, or adds it
            from `other` if not found.
            """
            # Create a mapping from tag name to element, as that's what we are fltering with
            mapping = {(el.tag, hashabledict(el.attrib)): el for el in one}
            for el in other:
                if len(el) == 0:
                    # Not nested
                    try:
                        # Update the text
                        mapping[(el.tag, hashabledict(el.attrib))].text = el.text
                    except KeyError:
                        # An element with this name is not in the mapping
                        mapping[(el.tag, hashabledict(el.attrib))] = el
                        # Add it
                        one.append(el)
                else:
                    try:
                        # Recursively process the element, and update it in the same way
                        self.combine_element(mapping[(el.tag, hashabledict(el.attrib))], el)
                    except KeyError:
                        # Not in the mapping
                        mapping[(el.tag, hashabledict(el.attrib))] = el
                        # Just add it
                        one.append(el)
    
    if __name__ == '__main__':
    
        r = XMLCombiner(sys.argv[1:-1]).combine()
        print '-'*20
        print et.tostring(r.getroot())
        r.write(sys.argv[-1], encoding="iso-8859-1", xml_declaration=True)
    

提交回复
热议问题