python - 从 XML 中删除重复元素
问题描述
在我来到这里之前,我已经搜索了类似的可能问题来帮助我,但是没有一个能解决我的问题。
我有一个包含电影信息的 xml 文件。我想要的是删除<title>
. 波纹管有一些部分的xml:
<imdb>
<movie>
<title>Alexander and the Terrible, Horrible, No Good, Very Bad Day</title>
<production_year>2009</production_year>
<producer>Moritz, Neal H.</producer>
<distributor>Columbia Pictures [us]</distributor>
<distributor>Columbia Pictures [us]</distributor>
</movie>
<movie>
<title>Blood and Donuts</title>
<production_year>2000</production_year>
<actor>Kauffmann, Matthew</actor>
<actor>Benedetto, Marisa</actor>
<producer>Schwarz, Jeffrey</producer>
<director>Schwarz, Jeffrey</director>
</movie>
<movie>
<title>Alexander and the Terrible, Horrible, No Good, Very Bad Day</title>
<production_year>2009</production_year>
<producer>Moritz, Neal H.</producer>
<distributor>Columbia Pictures [us]</distributor>
<distributor>Columbia Pictures [us]</distributor>
</movie>
</imdb>
如您所见,里面有两个“亚历山大与恐怖,可怕,不好,非常糟糕的一天”电影标题。我想删除所有重复的元素(就像这个例子一样,xml 中还有其他元素),最后,创建一个没有重复值的新 xml 文件。
所需的新 xml 应如下所示:
<imdb>
<movie>
<title>Alexander and the Terrible, Horrible, No Good, Very Bad Day</title>
<production_year>2009</production_year>
<producer>Moritz, Neal H.</producer>
<distributor>Columbia Pictures [us]</distributor>
<distributor>Columbia Pictures [us]</distributor>
</movie>
<movie>
<title>Blood and Donuts</title>
<production_year>2000</production_year>
<actor>Kauffmann, Matthew</actor>
<actor>Benedetto, Marisa</actor>
<producer>Schwarz, Jeffrey</producer>
<director>Schwarz, Jeffrey</director>
</movie>
</imdb>
我从这里看到了这个例子Python 从 xml 树中删除了重复的元素,但对我不起作用。我试过的代码不是我的。我做了一些更改来修改我需要的东西,但没有奏效。你们能帮我解决这个问题吗?谢谢您的帮助。
import xml.etree.ElementTree as ET
path = 'imdb.xml'
tree = ET.parse(path)
root = tree.getroot()
prev = None
def elements_equal(e1, e2):
if type(e1) != type(e2):
return False
if e1.tag != e2.tag: return False
if e1.text != e2.text: return False
if e1.tail != e2.tail: return False
if e1.attrib != e2.attrib: return False
if len(e1) != len(e2): return False
return all([elements_equal(c1, c2) for c1, c2 in zip(e1, e2)])
for page in root: # iterate over pages
elems_to_remove = []
for elem in page:
if elements_equal(elem, prev):
print("found duplicate: %s" % elem.text) # equal function works well
elems_to_remove.append(elem)
continue
prev = elem
for elem_to_remove in elems_to_remove:
page.remove(elem_to_remove)
# [...]
tree.write("new_imdb.xml")
更新 !
我尝试使用 xslt。它适用于我的示例,但是当我运行整个 imdb.xml 时它不起作用。它不会删除重复的条目。有什么帮助吗?
那是我使用的代码:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="imdbMovie" match="movie" use="concat(title,' ',production_year)"/>
<xsl:template match="imdb">
<xsl:copy>
<xsl:for-each select="movie[count(. | key('imdbMovie',concat(title,' ',production_year))[1]) = 1]">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
解决方案
这是一个解决方案。
from simplified_scrapy import SimplifiedDoc, utils, req
xml = '''
<imdb>
<movie>
<title>Alexander and the Terrible, Horrible, No Good, Very Bad Day</title>
<production_year>2009</production_year>
<producer>Moritz, Neal H.</producer>
<distributor>Columbia Pictures [us]</distributor>
<distributor>Columbia Pictures [us]</distributor>
</movie>
<movie>
<title>Blood and Donuts</title>
<production_year>2000</production_year>
<actor>Kauffmann, Matthew</actor>
<actor>Benedetto, Marisa</actor>
<producer>Schwarz, Jeffrey</producer>
<director>Schwarz, Jeffrey</director>
</movie>
<movie>
<title>Alexander and the Terrible, Horrible, No Good, Very Bad Day</title>
<production_year>2009</production_year>
<producer>Moritz, Neal H.</producer>
<distributor>Columbia Pictures [us]</distributor>
<distributor>Columbia Pictures [us]</distributor>
</movie>
</imdb>
'''
doc = SimplifiedDoc(xml)
movies = doc.selects('movie')
dic = {}
for movie in movies:
title = movie.title.text
if dic.get(title): # Use dictionary to remove duplicate
movie.remove() # Delete duplicate nodes
else:
dic[title]=True
print(doc.html)
推荐阅读
- amazon-sqs - 使用 AWS SQS 并发布到 Azure 服务总线
- apache-beam - Apache Beam:不可见的参数类型异常
- facebook-graph-api - 从 Facebook Instagram API 一次查询中获取有关所有媒体对象的信息
- android - 收听底部工作表对话框片段解除并打开一个新片段
- javascript - 使用 Nodejs 的 SendGrid 模板中的变量替换不起作用
- c# - 在统一编辑器中工作,但不是在构建之后
- javascript - HTML Javascript onclick 功能不起作用
- javascript - 使用 JavaScript 和 CSS 并排创建一个盒子
- grails - Spock 测试返回一个空模型
- python - 使用 python re 编辑文本文件