SAXを使用してPythonで大きなXMLファイルをサブファイルに分割する

JPeraita

非常に大きなXMLファイル(3〜5 GBの範囲)を解析する必要があります。これは、XMLノードに含まれるデータに従っていくつかの小さなXMLファイルに分割する必要があります。

<measure>この(非常に)単純化されたフラグメントのように、各入力ファイルには数十万の要素が含まれています

    <items>
        <measure code="0810">
            <condition sequ="001" SID="-5041162"/>
            <footnote Id="00550"/>
            <footnote Id="00735"/>
        </measure>
        <measure code="6304">
            <component Id="01" national="1"/>
            <footnote Id="00001"/>
        </measure>
        <measure code="0811">
            <condition sequ="002" SID="-5041356"/>
            <footnote Id="00555"/>
        </measure>
        <measure code="2915">
            <component Id="01" national="0"/>
            <certif SID="-737740"/>
            <certif SID="-737780"/>
        </measure>
    </items>

実際の<measure>要素のコンテンツは、ほとんどすべての整形式XMLにすることができます。

これらのファイルを解析するときに、2つのプロセスを実行する必要があります。

  1. <measure>要素のコンテンツから情報を抽出し、MongoDBデータベースにダンプします(この部分は解決されています...)
  2. <measure>ノードの「コード」属性の最初の2桁に基づいて、元のXMLファイルをたとえば100個のXMLサブファイルに分割します。つまり、新しい100個のXMLファイル(「part_00.xml」から「part_99.xml」という名前)を作成し、各<measure>要素を対応するサブファイルに追加する必要があります。すなわち、<measure>試料内のブロック1及び3「part_08.xml」にコピーする必要があり、ブロック2「part_63.xml」にコピーされなければなりません...

SAXを使用して元のファイルを解析していますが、上記のプロセス1は正常に実行されます。SAXプロセスの純粋なスケルトンは次のとおりです。

    import sys
    from xml.sax import ContentHandler
    from xml.sax import make_parser

    class ParseMeasures(ContentHandler):
        code = ''

        def startElement(self, name, attrs):
            if name == 'measure':
                self.code = attrs.get('code')

        def endElement(self, name):
            if name == 'measure':
                print('***Must append <measure> block to file part_{0}.xml'.format(self.code[:2]))

    def main(args):
        handler = ParseMeasures()
        sax_parser = make_parser()
        sax_parser.setContentHandler(handler)
        sax_parser.parse('my_large_xml.file.xml')
        print('Ended')

    if __name__ == '__main__':
        main(sys.argv[1:])

必要なのは<measure>、「endElement()」でXML要素全体にアクセスして、対応するサブファイルに追加できるようにすることです。

SAXを他のXML解析機能と組み合わせて<measure>、「endElement()」でXML要素全体を取得できるようにする方法はありますか?(サブファイルの作成と管理を処理できます...これは問題ではありません!)

それとも、そもそもこの状況ではSAXアプローチが最適ではないのでしょうか。

「唯一の」警告は、プロセスが3〜5GBの範囲の入力ファイルを処理する必要があるということです。

トマラク

以下は、組み込みのSAXパーサーを使用して解析イベントを生成し、lxmlを使用して部分ツリー(<measure>要素のみ、一度に1つのみ)を構築するハイブリッドソリューションです

要素が構築されると、lxmlのAPIによってシリアル化され、の値に応じて、増分XMLをさまざまなファイルに生成します@code

このコードは、<measure>要素内のあらゆるレベルのネスト、および空白を含むテキスト値を処理します。現在、コメント、処理命令、または名前空間は処理されませんが、それらのサポートが追加される可能性があります。

入力ファイルが大きい場合でも、メモリ消費量は低く抑える必要があります。lxmlはオーバーヘッドを追加しますが、反復書き込みサポートは非​​常に便利です。これを完全に手動で行うと、全体的に高速になりますが、より複雑になります。

from xml.sax import ContentHandler, make_parser
from lxml import etree

class ParseMeasures(ContentHandler):
    def __init__(self):
        self.stack = []
        self.open = False
        self.elem = None
        self.writers = {}
        self.text = []

    def _get_writer(self, filename):
        with etree.xmlfile(filename) as xf:
            with xf.element('items'):
                while True:
                    el = (yield)
                    xf.write(el)
                    xf.flush()  # maybe don't flush *every* write

    def _write(self):
        grp = self.elem.attrib['code'][0:2]

        if grp in self.writers:
            writer = self.writers[grp]
        else:
            writer = self.writers[grp] = self._get_writer('part_%s.xml' % grp)
            next(writer)        # run up to `yield` and wait

        writer.send(self.elem)  # write out current `<measure>`
        self.elem = None

    def _add_text(self):
        if self.elem is not None and self.text:
            if self.open:
                self.elem.text = ''.join(self.text)
            else:
                self.elem.tail = ''.join(self.text)
            self.text = []

    def startElement(self, name, attrib):
        if self.stack or name == 'measure':
            self._add_text()
            self.open = True
            self.elem = etree.Element(name, attrib)
            self.stack.append(self.elem)
            if len(self.stack) > 1:
                self.stack[-2].append(self.elem)

    def characters(self, content):
        if self.elem is not None:
            self.text.append(content)

    def endElement(self, name):
        if self.stack:
            self._add_text()
            self.open = False
            self.elem = self.stack.pop()            
            if not self.stack:
                self._write()

    def endDocument(self):
        # clean up
        for writer in self.writers:
            self.writers[writer].close()


def main():
    sax_parser = make_parser()
    sax_parser.setContentHandler(ParseMeasures())
    sax_parser.parse(r'test.xml')

if __name__ == '__main__':
    main()

これにより、 part_08.xml

<items>
    <measure code="0810">
        <condition sequ="001" SID="-5041162"/>
        <footnote Id="00550"/>
        <footnote Id="00735"/>
    </measure>
    <measure code="0811">
        <condition sequ="002" SID="-5041356"/>
        <footnote Id="00555"/>
    </measure>
</items>

そして part_29.xml

<items>
    <measure code="2915">
        <component Id="01" national="0"/>
        <certif SID="-737740"/>
        <certif SID="-737780"/>
    </measure>
</items>

そして part_63.xml

<items>
    <measure code="6304">
        <component Id="01" national="1"/>
        <footnote Id="00001"/>
    </measure>
</items>

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

大きなXMLファイルを小さなファイルに分割する

分類Dev

WindowsでSystemCommandTaskletを使用して大きなファイルを分割する

分類Dev

Pythonで非常に大きなファイルを小さなファイルに分割する-開いているファイルが多すぎる

分類Dev

非常に大きなPythonファイルを分割する方法は?

分類Dev

Pythonで大きなデータファイルを分割する

分類Dev

Pythonでgzipを使用して大きなファイルを圧縮する

分類Dev

PowerShellを使用してユーザー定義の行で大きなExcelファイルを複数の小さなファイルに分割する

分類Dev

XDocumentを使用して大きなXMLファイルをループする

分類Dev

大きなファイルを小さなファイルに分割する

分類Dev

Javaを使用してより大きなサイズのXMLファイルを分割する(親の属性と兄弟を保持する)

分類Dev

大きなxmlファイルをn個のグループに分割する

分類Dev

Pythonで大きなXMLファイルを解析する方法は?

分類Dev

大きなxmlファイルでphpを使用する方法は?

分類Dev

python3は、大きなファイルを区切り文字で小さなファイルに分割します(サイズ、行ではありません)

分類Dev

大きな HTML ファイルを複数のファイルに分割する

分類Dev

1つの大きなcsvファイルを分割して2列でリサンプリングする

分類Dev

VTD-XMLを使用して大きなXMLファイルを小さなチャンクに分割するときの例外

分類Dev

SAX(Java)で大きなXMLファイルを解析しながらDOMにローカルチャンクをロードする

分類Dev

Powershellを使用してXMLファイルをより小さなファイルに分割する方法

分類Dev

fastparquetを使用してparquetファイルをサブファイルに分割する

分類Dev

Pythonとパンダを使用して、誤って作成された大きなcsvファイルをタブ区切りファイルに変換する

分類Dev

Smooksなどを使用してXMLファイルを要素ごとに分割する

分類Dev

javascriptを使用して大きなCSVファイルを複数の小さなCSVファイルに分割し、反応する

分類Dev

大きなファイルをチャンクに分割する

分類Dev

大きなファイルをチャンクに分割する

分類Dev

Windowsで大きなファイルを分割する方法は?

分類Dev

lxmlとpythonを使用してxmlファイルのサブツリーをきれいに出力する方法は?

分類Dev

Camel、フィールド条件を使用して、ヘッダー付きの大きなXMLファイルを分割

分類Dev

大きなファイルを効率的に分割する(現在awkを使用)

Related 関連記事

  1. 1

    大きなXMLファイルを小さなファイルに分割する

  2. 2

    WindowsでSystemCommandTaskletを使用して大きなファイルを分割する

  3. 3

    Pythonで非常に大きなファイルを小さなファイルに分割する-開いているファイルが多すぎる

  4. 4

    非常に大きなPythonファイルを分割する方法は?

  5. 5

    Pythonで大きなデータファイルを分割する

  6. 6

    Pythonでgzipを使用して大きなファイルを圧縮する

  7. 7

    PowerShellを使用してユーザー定義の行で大きなExcelファイルを複数の小さなファイルに分割する

  8. 8

    XDocumentを使用して大きなXMLファイルをループする

  9. 9

    大きなファイルを小さなファイルに分割する

  10. 10

    Javaを使用してより大きなサイズのXMLファイルを分割する(親の属性と兄弟を保持する)

  11. 11

    大きなxmlファイルをn個のグループに分割する

  12. 12

    Pythonで大きなXMLファイルを解析する方法は?

  13. 13

    大きなxmlファイルでphpを使用する方法は?

  14. 14

    python3は、大きなファイルを区切り文字で小さなファイルに分割します(サイズ、行ではありません)

  15. 15

    大きな HTML ファイルを複数のファイルに分割する

  16. 16

    1つの大きなcsvファイルを分割して2列でリサンプリングする

  17. 17

    VTD-XMLを使用して大きなXMLファイルを小さなチャンクに分割するときの例外

  18. 18

    SAX(Java)で大きなXMLファイルを解析しながらDOMにローカルチャンクをロードする

  19. 19

    Powershellを使用してXMLファイルをより小さなファイルに分割する方法

  20. 20

    fastparquetを使用してparquetファイルをサブファイルに分割する

  21. 21

    Pythonとパンダを使用して、誤って作成された大きなcsvファイルをタブ区切りファイルに変換する

  22. 22

    Smooksなどを使用してXMLファイルを要素ごとに分割する

  23. 23

    javascriptを使用して大きなCSVファイルを複数の小さなCSVファイルに分割し、反応する

  24. 24

    大きなファイルをチャンクに分割する

  25. 25

    大きなファイルをチャンクに分割する

  26. 26

    Windowsで大きなファイルを分割する方法は?

  27. 27

    lxmlとpythonを使用してxmlファイルのサブツリーをきれいに出力する方法は?

  28. 28

    Camel、フィールド条件を使用して、ヘッダー付きの大きなXMLファイルを分割

  29. 29

    大きなファイルを効率的に分割する(現在awkを使用)

ホットタグ

アーカイブ