我有一个非常大的(7GB)MediaWiki XML转储,它包含对Wiki的每个页面进行的每个更改的记录 . 我正在尝试记录哪些用户为每个页面做出了贡献,因此我想从XML中提取它 .
XML看起来像:
<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.3/">
<page>
<title>Unique Page title</title>
<id>11</id>
<restrictions>sysop</restrictions>
<revision>
<id>11</id>
<timestamp>2005-10-26T02:23:03Z</timestamp>
<contributor>
<ip>MediaWiki default</ip>
</contributor>
<text xml:space="preserve">i</text>
</revision>
</page>
<page> ... </page>
<page> ... </page>
...
</mediawiki>
对于这个大小的文件,我相信我需要使用iterparse . 现在,我只是想打印 Headers ,但是当我运行以下代码时,它会打印出“无” .
NS = '{http://www.mediawiki.org/xml/export-0.3/}'
from xml.etree.ElementTree import iterparse
with open('XMLFile.xml') as f:
for event, elem in iterparse(f):
if elem.tag == NS + 'page':
for node in elem:
if node.tag == NS + 'title':
print node.text()
elem.clear()
3 回答
尝试在迭代解析期间直接拉出'title'元素,而不是执行辅助循环:
似乎对我有用 .
我没有使用Python和iterparse的经验,但一般来说,使用迭代XML解析器执行此操作的方式如下:
在解析循环之外,设置变量以存储当前页面 Headers 和贡献者列表 .
在循环内部,每当打开
page
标记时,重置变量 .遇到
title
标记时,将页面 Headers 变量设置为其内容 .遇到
contributor
标记时,将其内容添加到贡献者列表中 .当
page
标记关闭时,输出收集的 Headers 和贡献者列表 .打印
title
元素的文本内容时会得到None
,因为您使用的是elem.clear() "too early" . 默认情况下,iterparse()仅生成"end"事件 . 发出page
的"end"事件时,其所有子元素(包括title
)都已清除(清空) .如果问题中的代码中的
elem.clear()
只向右移动一个缩进级别(四个空格),它将按预期工作 . 使代码工作的另一种方法是将iterparse(f)
更改为iterparse(f, events=["start"])
.node.text()
应为node.text
.有关
iterparse()
的更多详细信息,请参见http://effbot.org/zone/element-iterparse.htm .假设XML转储(mw.xml)如下所示:
以下是关于如何获得头衔和贡献者的建议:
输出:
我假设你想要贡献者的用户名 . 根据最新的XML Schema,
contributor
可以包含username
,ip
和/或id
子元素(对于0.3版本的模式也是如此) .