Разделение большого XML-файла на несколько файлов - PullRequest
2 голосов
/ 08 мая 2019

Я пытался разбить большой XML-файл (65 ГБ), используя следующий код, но это занимает много времени (я думаю, из-за конкатенации строк) формат XML похож на

<posts>
<row id= ....   />
<row id= ....   />
<row id= ....   />
<row id= ....   />
.
.
.
</posts>

from lxml import etree

context = etree.iterparse('Posts.xml', tag='row', events=('end', ))
index = 0
count = 0
full_text = b""
for event, elem in context:
    count += 1
    full_text += etree.tostring(elem)
    if count >= 1000000 :
        count = 0
        index += 1
        filename = format(str(index) + ".xml")
        with open(filename, 'wb') as f:
            f.write(b"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
            f.write(b"<root>\n")
            f.write(full_text)
            f.write(b"</root>")
            full_text = b""
with open(format(str(index+1)+".xml"), 'wb') as f:
    f.write(b"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
    f.write(b"<root>\n")
    f.write(full_text)
    f.write(b"</root>")

Я хочу разделить его на файлы размером 1 ГБ для дальнейшей обработки

Есть ли эффективный способ обосновать следующий код?

P.S. [Те же темы не помогли]

1 Ответ

0 голосов
/ 08 мая 2019

Я не могу получить вас до конца, но ниже я подхожу к этому.

Я бы начал с:

from lxml import html
import lxml.etree as le

tree = html.fromstring(content) #content would be your whole file

Затем я бы посчитал числоузлов в ваших tree, таким образом:

num_nodes = tree.xpath("count(//book)") #'book' in your case would be whatever the critical item is

Получив это число, я бы определил, на сколько файлов я бы разделил эти узлы.Допустим, у вас есть 12 узлов, и вы решили разделить их на 3 файла, узлы 1-4 будут в file 1, 5-8 в file 2 и т. Д. Давайте сосредоточимся на file 2:

От вашегоtree вам нужно выбрать узлы в позициях, назначенных file 2.Итак, для этого файла:

low_pos=5
hi_pos=8
items = tree.xpath('//book[position()>=low_pos and position()<=hi_pos]')

Это должно выбрать соответствующие узлы и все их теги, текст и т. Д.

Наконец, вы берете каждый из элементов и делаете с ним чтовы будете:

for item in items:
    print(le.tostring(item).decode('utf-8'))#or write or whatever

Очевидно, что для его реализации в вашем случае потребуется много работы, но, надеюсь, это по крайней мере начало ...

...