2009-01-25 38 views
9

Tôi đang tìm cách tách một tệp XML lớn thành các bit nhỏ hơn. Tôi muốn quét qua các tập tin tìm kiếm một thẻ cụ thể, sau đó lấy tất cả các thông tin giữa và, sau đó lưu nó vào một tập tin, sau đó tiếp tục thông qua phần còn lại của tập tin.Tách một tệp XML lớn trong Python

Vấn đề của tôi đang cố gắng tìm một cách sạch sẽ cần lưu ý khi bắt đầu và kết thúc của thẻ, để tôi có thể lấy các văn bản bên trong như tôi quét qua các tập tin với "cho dòng trong f"

tôi d thay vì không sử dụng các biến sentinel. Có cách nào để thực hiện điều này không?

Tệp quá lớn để đọc vào bộ nhớ.

+1

Hãy thử http://stackoverflow.com/search?q=iterparse – jfs

+0

nếu bạn sử dụng Jython và 64bit JVM, bạn có thể sử dụng mở rộng VTD-xml để làm tách, thanh lịch nhất/đơn giản/hiệu quả loại –

Trả lời

6

Bạn có thể xem xét sử dụng chức năng ElementTree iterparse cho trường hợp này.

+0

ElementTree là trong stdlib – jfs

+1

Cảm ơn Jeff - không chỉ làm điều này thuần hóa một bộ nhớ hog, nhưng bây giờ tôi có 3 dòng mã thay vì 20 –

9

Có hai cách phổ biến để xử lý dữ liệu XML.

Một được gọi là DOM, viết tắt của Mô hình đối tượng tài liệu. Kiểu phân tích cú pháp XML này có lẽ là những gì bạn đã thấy khi xem tài liệu, vì nó đọc toàn bộ XML trong bộ nhớ để tạo ra mô hình đối tượng.

Điểm thứ hai được gọi là SAX, là phương thức phát trực tuyến. Trình phân tích cú pháp bắt đầu đọc XML và gửi các tín hiệu đến mã của bạn về các sự kiện nhất định, ví dụ: khi tìm thấy thẻ bắt đầu mới.

Vì vậy, SAX rõ ràng là những gì bạn cần cho hoàn cảnh của mình. Bộ phân tích cú pháp Sax có thể được tìm thấy trong thư viện trăn dưới xml.saxxml.parsers.expat.

+0

+1: SAX phân hủy các tài liệu XML lớn. –

+0

vtd-xml tốt hơn rất nhiều so với dom hoặc sax –

+1

Dường như với vtd-xml là DOM.Bạn có thể gọi nó là "truy cập ngẫu nhiên" hoặc "tài liệu tập trung" nhưng đó vẫn là DOM. Dường như vtd-xml có phân tích và lập chỉ mục mạnh mẽ nhưng vẫn là DOM. –

1

Làm thế nào serendipitous! Will Larson vừa đăng một bài tốt về Handling Very Large CSV and XML File in Python.

Các bản chính có vẻ là sử dụng mô-đun xml.sax, như Văn đã đề cập và để thực hiện một số chức năng macro trừu tượng hóa các chi tiết của API SAX cấp thấp.

6

Tôi đã thành công với phương pháp cElementTree.iterparse để thực hiện một tác vụ tương tự.

Tôi đã có tài liệu xml lớn với các 'mục nhập' lặp lại với thẻ 'resFrame' và tôi muốn lọc các mục nhập cho một id cụ thể. Đây là mã mà tôi sử dụng cho nó:

tài liệu nguồn có cấu trúc này

<snapDoc> 
    <bucket>....</bucket> 
    <bucket>....</bucket> 
    <bucket>....</bucket> 
    ... 
    <resFrame><id>234234</id>.....</resFrame> 
    <frame><id>344234</id>.....</frame> 
    <resFrame>...</resFrame> 
    <frame>...</frame> 
</snapDoc> 

tôi đã sử dụng các kịch bản sau đây để tạo ra một doc nhỏ hơn mà có cùng cấu trúc, mục xô và các mục resFrame chỉ với một id cụ thể.

#!/usr/bin/env python2.6 

import xml.etree.cElementTree as cElementTree 
start = '''<?xml version="1.0" encoding="UTF-8"?> 
<snapDoc>''' 

def main(): 
    print start 
    context = cElementTree.iterparse('snap.xml', events=("start", "end")) 
    context = iter(context) 
    event, root = context.next() # get the root element of the XML doc 

    for event, elem in context: 
     if event == "end": 
      if elem.tag == 'bucket': # i want to write out all <bucket> entries 
       elem.tail = None 
       print cElementTree.tostring(elem) 
      if elem.tag == 'resFrame': 
       if elem.find("id").text == ":4:39644:482:-1:1": # i only want to write out resFrame entries with this id 
        elem.tail = None 
        print cElementTree.tostring(elem) 
      if elem.tag in ['bucket', 'frame', 'resFrame']: 
       root.clear() # when done parsing a section clear the tree to safe memory 
    print "</snapDoc>" 

main() 
0

Đây là bài viết cũ, nhưng rất hay từ Uche Ogbuji cũng rất tốt Python & Cột XMl. Nó bao gồm câu hỏi chính xác của bạn và sử dụng mô-đun sax chuẩn lib như câu trả lời khác đã gợi ý. Decomposition, Process, Recomposition

Các vấn đề liên quan