【发布时间】:2020-01-16 04:36:31
【问题描述】:
我有第一个文件(大小约为 1-3 kb),其中几行如下所示::
Name1
Name2
Name3
Name4
etc
还有第二个文件(大小为 1.2 GB),其中的字符串如下所示:
<root><img>url</img><title>Name1</title>(a few more tags there)</root>
第二个文件包含第一个文件的所有名称(以及与 file1 相同的文件的名称),但包含附加信息。
我需要一个代码来遍历 file1 的每一行,从那里获取名称并在文件 2 中查找包含相同名称的标记。找到包含所需名称的标记后,需要复制父级根标签及其中的所有内容输出文件。
我得到了这个代码:
root = ET.parse('file2.xml').getroot()
with open('output.xml', 'a') as x, open('file1.xml', 'r') as f:
for line in f:
element = line
search = root.xpath('.//root/Title[text()="%s"]' % element)
for i in search:
print(ET.tostring(i.getparent().decode('utf-8')))
它可以工作,但速度很慢,我需要加快这段代码的速度
问题:我怎样才能加快这段代码的速度,或者是否有另一种快速的方法来逐文本搜索元素?
编辑
大文件中每一行的结构(印刷精美)
<root>
<Big_Images>
<Big_Images0>url to img</Big_Images0>
<Big_Images1>url to img</Big_Images1>
</Big_Images>
<Small_Images>
<Small_Images0>url to small img</Small_Images0>
<Small_Images1>url to small img</Small_Images1>
</Small_Images>
<title>Name1</title>
<Summary/> # can contain some info
<Price>4.1</Price>
<Main_Info>
<item>many html code there</item>
</Main_Info>
</root>
Small_Images(number from 0(<Small_Images/>) to 10) 总是等于 Big_Images(number from 0(<Big_Images/>) to 10)
我还删除了所有重复的字符串(在一个大文件中)。要么没有包含例如 Name1 的字符串,要么只有 1 个包含 Name1 的字符串。
root 总是包含 1 个title 标签
只有 Summary 、 Big_Images 和 Small_Images 可能没有元素
在xml文件中有1个父标签data,每一行都有一个root
【问题讨论】:
-
Idea1:
.//root/title可能效率低下。请改用/root/title(这假设<root>确实是您的XML 文件的根标记。如果不是,请适当调整)。想法2:不是顺序读取小文件,随机搜索大文件,而是先将小文件读入内存(例如读入一个集合),然后依次读入大文件,然后在内存中查找集合中的名称。 -
就 XPath 而言,显式选择
root/Title然后使用i.getparent似乎有点奇怪,似乎直接使用search = root.xpath('.//root[title ="%s"]' % element)然后简单地使用print(ET.tostring(i.decode('utf-8')))就足够了。我没有进行任何测试是否可以提高性能。一般来说,对于这么大的数据(1.2 GB),使用像 BaseX 这样的数据库可能是有意义的,因为它允许您构建索引,然后搜索变得更快。 BaseX 是用 Java 实现的,但有一个 Python 客户端 API docs.basex.org/wiki/Clients。 -
如果您提供有关确切文件结构的更多详细信息会有所帮助,特别是是否存在或是否存在具有相同值的多个
title元素(例如,多个<title>Name1</title>元素)?title元素的父元素是否总是root元素?这些title元素的嵌套级别是始终相同还是不同级别? -
我更新了表头的数据。