0

巨大な 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 は、ウィキペディアのすべてのページをページ要素の形式で構成しています。ウィキペディアのすべてのページのページからタイトルエントリの値を抽出し、(簡単にするために) それらを印刷すると仮定するパーサーを作成する必要があります。

Pythonを使用して同じものを構築しようとしています(ただし、解決策があれば言語の切り替えを受け入れます)。私が知っている唯一の方法は、ElementTreeを使用することです。

ただし、関数 parse('file.xml') を使用するには、最初にドキュメント全体を完全に解析する必要があり、その後結果が出力されます。明らかなように、xml 全体がページ要素で構成されていることがわかります。xml の残りの部分を解析している間に、プログラムでタイトルの印刷を開始したいと考えています。それも可能ですか?もしそうなら、どのように?

編集注:質問を簡単にするために、ここでタイトルを抽出する例を引用します。ただし、将来同じものを抽出する必要があるため、xml 解析機能が必要です。

4

3 に答える 3

3

必要なのは、イベント ベースの XML ライブラリです。ドキュメント全体のツリーを作成するのではなく、段階的に解析するときに断片を送信します。典型的な答えはxml.sax stdlib モジュールですが、他にもたくさんあると思います。

于 2013-04-08T23:58:24.330 に答える
1

このような大規模なデータセットを使用しようとしたことはありませんが、lxml モジュールが高速で便利であることがわかりました。

ここの lxml.etree チュートリアルは、有益な例を提供します。

重要な段落は次のとおりです。

iterparse() の非常に重要な使用例は、生成された大きな XML ファイル (データベース ダンプなど) の解析です。ほとんどの場合、これらの XML 形式には、ルート ノードのすぐ下にぶら下がり、何千回も繰り返される主要なデータ項目要素が 1 つしかありません。この場合、lxml.etree にツリー構築を行わせ、データ抽出に通常のツリー API を使用して、この 1 つの要素だけを正確にインターセプトするのがベスト プラクティスです。

于 2013-04-09T01:59:19.830 に答える
0

もちろん可能です。醜い方法では、テキストモードでファイルを行単位で読み取ることができます。次に、正規表現または単純な文字列検索方法 (キーワード as and ) をフィルターとして使用して、行を次の形式で取得します。

<title>AccessibleComputing</title>

その後、タイトルを取得して、やりたいことができます。

于 2013-04-08T23:49:46.460 に答える