我有一个巨大的xml文件(当前维基百科转储)。这个大小约为45 GB的xml表示当前维基百科的全部数据。文件的前几行是(更多的输出):
<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.8/" xmlns:xsi="http://ww
w.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/x
ml/export-0.8/ http://www.mediawiki.org/xml/export-0.8.xsd" version="0.8" xml:la
ng="en">
<siteinfo>
<sitename>Wikipedia</sitename>
<base>http://en.wikipedia.org/wiki/Main_Page</base>
<generator>MediaWiki 1.21wmf6</generator>
<case>first-letter</case>
<namespaces>
<namespace key="-2" case="first-letter">Media</namespace>
<namespace key="-1" case="first-letter">Special</namespace>
<namespace key="0" case="first-letter" />
<namespace key="1" case="first-letter">Talk</namespace>
<namespace key="2" case="first-letter">User</namespace>
<namespace key="3" case="first-letter">User talk</namespace>
<namespace key="4" case="first-letter">Wikipedia</namespace>
<namespace key="5" case="first-letter">Wikipedia talk</namespace>
<namespace key="6" case="first-letter">File</namespace>
<namespace key="7" case="first-letter">File talk</namespace>
<namespace key="8" case="first-letter">MediaWiki</namespace>
<namespace key="9" case="first-letter">MediaWiki talk</namespace>
<namespace key="10" case="first-letter">Template</namespace>
<namespace key="11" case="first-letter">Template talk</namespace>
<namespace key="12" case="first-letter">Help</namespace>
<namespace key="13" case="first-letter">Help talk</namespace>
<namespace key="14" case="first-letter">Category</namespace>
<namespace key="15" case="first-letter">Category talk</namespace>
<namespace key="100" case="first-letter">Portal</namespace>
<namespace key="101" case="first-letter">Portal talk</namespace>
<namespace key="108" case="first-letter">Book</namespace>
<namespace key="109" case="first-letter">Book talk</namespace>
<namespace key="446" case="first-letter">Education Program</namespace>
<namespace key="447" case="first-letter">Education Program talk</namespace
>
<namespace key="710" case="first-letter">TimedText</namespace>
<namespace key="711" case="first-letter">TimedText talk</namespace>
</namespaces>
</siteinfo>
<page>
<title>AccessibleComputing</title>
<ns>0</ns>
<id>10</id>
<redirect title="Computer accessibility" />
<revision>
<id>381202555</id>
<parentid>381200179</parentid>
<timestamp>2010-08-26T22:38:36Z</timestamp>
<contributor>
<username>OlEnglish</username>
<id>7181920</id>
</contributor>
<minor />
<comment>[[Help:Reverting|Reverted]] edits by [[Special:Contributions/76.2
8.186.133|76.28.186.133]] ([[User talk:76.28.186.133|talk]]) to last version by
Gurch</comment>
<text xml:space="preserve">#REDIRECT [[Computer accessibility]] {{R from C
amelCase}}</text>
<sha1>lo15ponaybcg2sf49sstw9gdjmdetnk</sha1>
<model>wikitext</model>
…等等
注意树中的页元素。它对应的是维基百科中一个独特的页面。给定的XML以页面元素的形式包含了Wikipedia的所有页面。我需要写一个解析器,我需要从维基百科所有页面的页面中提取标题条目的值,并假设(为了简单起见)打印它们。我正在尝试使用Python构建相同的(尽管我对语言切换持开放态度,如果这提供了解决方案)。我所知道的唯一方法是使用ElementTree。
然而,使用函数parse('file.xml')需要首先完全解析整个文档,然后输出任何结果。很明显,我知道整个xml是由页面元素组成的。我希望程序在解析xml的其余部分时开始打印标题。这可能吗?如果有,怎么做?
编辑注:我在这里引用了一个提取标题的例子,以使问题简单。但是,我确实需要xml解析功能,因为我需要在将来提取相同的功能。
您需要的是一个基于事件的XML库,它在增量解析时向您发送片段,而不是为整个文档创建树。典型的答案是xml。
我没有尝试使用这么大的数据集,但我发现lxml模块既快速又有用。
lxml。这里的Etree教程提供了一个可能具有指导意义的示例。
关键段落是:
iterparse()的一个非常重要的用例是解析生成的大型XML文件,例如数据库转储。大多数情况下,这些XML格式只有一个主数据项元素,它挂在根节点的正下方,并且重复了数千次。在这种情况下,最佳实践是让lxml。使用正常的树API进行数据提取,构建树并只精确地截取这一个元素。
当然有可能。以一种难看的方式,您可以在文本模式下逐行读取文件。然后使用正则表达式或简单的字符串搜索方法(关键字as And)作为过滤器来获取
格式的行。<title>AccessibleComputing</title>
然后,你可以得到标题,做你想做的。