1

我想使用 Python 比较 2 个 xml 并获得特定的输出。

例子:

旧的.xml

<foos>
    <foo>
        <id>1</id>
        <x>1</x>
    </foo>
    <foo>
        <id>2</id>
        <x>1</x>
    </foo>
    <foo>
        <id>3</id>
        <x>1</x>
        <y>1</y>
    </foo>
</foo>

新的.xml

<foos>
    <foo>
        <id>1</id>
        <x>2</x>
        <y>1</y>
    </foo>
    <foo>
        <id>2</id>
        <x>1</x>
    </foo>
    <foo>
        <id>3</id>
        <x>2</x>
        <y>1</y>
    </foo>
    <foo>
        <id>4</id>
        <x>1</x>
    </foo>
</foo>

我想要的输出:

输出.xml

<foos>
    <foo>
        <id>1</id>
        <x>2</x>
        <y>1</y>
    </foo>
    <foo>
        <id>3</id>
        <x>2</x>
    </foo>
    <foo>
        <id>4</id>
        <x>1</x>
    </foo>
</foo>

我写了一个性能很差的非常丑陋的函数,我想找到一种更好的方法来做到这一点。您对如何以良好的表现执行此任务有任何想法吗?

我遇到的一些问题;

  • 2 个 xml 的 ids 列表不相等(可以在 2 个 xml 之间删除或添加对象)
  • 输出的特定格式,阻止我使用经典库来完成这项工作(https://github.com/Shoobx/xmldiff)。但也许有一种解决方法?
4

1 回答 1

1

供您参考,也许这也是一种丑陋的方法。

import io
from simplified_scrapy import SimplifiedDoc, utils

def getChange(oldFile='old.xml', newFile='new.xml'):
    xmlOld = utils.getFileContent(oldFile)
    docOld = SimplifiedDoc(xmlOld)
    foo = docOld.selects('foo')
    dic = {}
    for f in foo:
        dic[f.id.text] = (f.x.text, f.y.text)

    xmlNew = utils.getFileContent(newFile)
    docNew = SimplifiedDoc(xmlNew)
    foo = docNew.selects('foo')
    change = {}
    for f in foo:
        old = dic.get(f.id.text)
        if not old:
            change[f.id.text] = (f.x.text, f.y.text)
        else:
            new = (f.x.text, f.y.text)
            if old[0] != new[0] and old[1] != new[1]:
                change[f.id.text] = (f.x.text, f.y.text)
            elif old[0] != new[0]:
                change[f.id.text] = (f.x.text, '')
            elif old[1] != new[1]:
                change[f.id.text] = ('', f.y.text)
    return change


def saveFile(change, output='output.xml'):
    with io.open(output, mode='w') as file:
        file.write(u'<foos>\n')
        for k, v in change.items():
            file.write('<foo><id>{}</id>'.format(k))
            if v[0]:
                file.write('<x>{}</x>'.format(v[0]))
            if v[1]:
                file.write('<y>{}</y>'.format(v[1]))
            file.write('</foo>\n')
        file.write('</foos>\n')


saveFile(getChange())
于 2020-11-06T06:12:18.007 回答