2011-08-27 33 views
6

Tệp đầu vào chứa hàng nghìn giao dịch ở định dạng XML có kích thước khoảng 10GB. Yêu cầu là chọn từng giao dịch XML dựa trên đầu vào của người dùng và gửi nó đến hệ thống xử lý.Đọc tệp XML khổng lồ bằng cách sử dụng tệp StAX và XPath

Nội dung mẫu của tập tin

<transactions> 
    <txn id="1"> 
     <name> product 1</name> 
     <price>29.99</price> 
    </txn> 

    <txn id="2"> 
     <name> product 2</name> 
     <price>59.59</price> 
    </txn> 
</transactions> 

The (kỹ thuật) sử dụng dự kiến ​​sẽ cung cấp cho các tên thẻ đầu vào như <txn>.

Chúng tôi muốn cung cấp giải pháp này chung chung hơn. Nội dung tệp có thể khác và người dùng có thể cung cấp biểu thức XPath như "//transactions/txn" để chọn các giao dịch riêng lẻ.

Có vài điều về kỹ thuật chúng ta phải xem xét ở đây

  • Các tập tin có thể được ở một vị trí chia sẻ hoặc FTP
  • Kể từ khi kích thước tập tin là rất lớn, chúng tôi không thể tải toàn bộ tập tin trong JVM

Chúng tôi có thể sử dụng trình phân tích cú pháp của StAX cho trường hợp này không? Nó phải có biểu thức XPath như một đầu vào và chọn/chọn giao dịch XML.

Tìm kiếm đề xuất. Cảm ơn trước.

+0

Tôi đề nghị là sử dụng mở rộng VTD-xml trong chế độ bản đồ mem và 64 bit jvm –

Trả lời

8

Stax và xpath là những thứ rất khác nhau. Stax cho phép bạn phân tích cú pháp một tài liệu XML trực tuyến theo một hướng chuyển tiếp. Xpath cho phép phân tích cú pháp theo cả hai hướng. Stax là một trình phân tích cú pháp XML trực tuyến rất nhanh, nhưng, nếu bạn muốn xpath, java có một thư viện riêng biệt cho điều đó.

Hãy nhìn vào câu hỏi này cho một cuộc thảo luận rất giống nhau: Is there any XPath processor for SAX model?

+2

Nếu bạn định downvote tôi, xin vui lòng để lại một bình luận. Bằng cách đó mọi người đều học! – Jon7

+0

Bỏ phiếu xuống vì tuyên bố của bạn "Stax và xpath là những điều rất khác nhau" là không chính xác. XPath (ít nhất là tập con của nó) vẫn có thể được thực hiện trong mô hình Stax (mô hình kéo). Nó được thực hiện trong C# https://msdn.microsoft.com/en-us/library/ms950778.aspx – TriCore

0

Bạn có cần xử lý nhanh hay bạn cần tra cứu nhanh trong dữ liệu? Những yêu cầu này cần cách tiếp cận khác nhau.

Để đọc nhanh toàn bộ dữ liệu, StAX sẽ ổn.

Nếu bạn cần tra cứu nhanh hơn bạn có thể cần tải nó vào một số cơ sở dữ liệu, Berkeley DB XML, ví dụ:

1

Đó chắc chắn là một trường hợp sử dụng cho XProc với một luồng và thực hiện xử lý song song như QuiXProc (http://code.google.com/p/quixproc)

Trong tình huống này, bạn sẽ phải sử dụng

<p:for-each> 
    <p:iteration-source select="//transactions/txn"/> 
    <!-- you processing on a small file --> 
    </p:for-each> 

Bạn thậm chí có thể wrapp mỗi kết quả chuyển đổi với một dòng đơn của XProc

<p:wrap-sequence wrapper="transactions"/> 

Hy vọng điều này sẽ giúp

1

Chúng tôi thường phân tích cú pháp 1GB + tệp XML phức tạp bằng cách sử dụng trình phân tích SAX thực hiện chính xác những gì bạn mô tả: Nó trích xuất một phần cây DOM có thể được truy vấn thuận tiện bằng XPATH.

Tôi bogged về nó here - Nó sử dụng SAX không phải là trình phân tích cú pháp StAX, nhưng có thể đáng xem.

13

Nếu hiệu suất là yếu tố quan trọng và/hoặc kích thước tài liệu lớn (cả hai trường hợp này ở đây), sự khác biệt giữa trình phân tích cú pháp sự kiện (như SAX hoặc StAX) và thực thi Java XPath gốc rằng sau này xây dựng một Tài liệu DOM W3C trước khi đánh giá biểu thức XPath. [Thật thú vị khi lưu ý rằng tất cả các triển khai của Mô hình đối tượng tài liệu Java như DOM hoặc Axiom đều sử dụng bộ xử lý sự kiện (như SAX hoặc StAX) để xây dựng biểu diễn trong bộ nhớ, vì vậy nếu bạn có thể nhận được chỉ với bộ xử lý sự kiện bạn tiết kiệm cả bộ nhớ và thời gian cần thiết để tạo DOM.]

Như tôi đã đề cập, việc triển khai XPath trong JDK hoạt động trên Tài liệu DOM W3C. Bạn có thể thấy điều này trong Java JDK mã nguồn thực hiện bằng cách nhìn vào com.sun.org.apache.xpath.internal.jaxp.XPathImpl, nơi trước khi đánh giá() phương pháp được gọi là phân tích cú pháp trước tiên phải phân tích các nguồn:

Document document = getParser().parse(source); 

Sau này 10GB của bạn của XML sẽ được đại diện trong bộ nhớ (cộng với bất kỳ chi phí nào) — có lẽ không phải là thứ bạn muốn. Mặc dù bạn có thể muốn có một giải pháp "chung" hơn, cả XPath và XML đánh dấu của bạn dường như tương đối đơn giản, vì vậy dường như không phải là sự biện minh thực sự cho XPath (ngoại trừ có lẽ là sang trọng lập trình). Điều tương tự cũng đúng đối với gợi ý XProc: điều này cũng sẽ xây dựng một DOM. Nếu bạn thực sự cần một DOM, bạn có thể sử dụng Axiom thay vì DOM W3C. Axiom có ​​một API thân thiện hơn nhiều và xây dựng DOM của nó trên StAX, vì vậy nó nhanh và sử dụng Jaxen để thực thi XPath của nó. Jaxen yêu cầu một số loại loại DOM (W3C DOM, DOM4J hoặc JDOM). Điều này sẽ đúng với tất cả các cài đặt XPath, vì vậy nếu bạn không thực sự cần XPath gắn bó với chỉ trình phân tích sự kiện sẽ được đề nghị.

SAX là API phát trực tuyến cũ, với StAX mới hơn và nhanh hơn rất nhiều. Hoặc sử dụng triển khai thực hiện JDK StAX gốc (javax.xml.stream) hoặc thực hiện STAX Woodstox (nhanh hơn đáng kể theo kinh nghiệm của tôi), tôi khuyên bạn nên tạo bộ lọc sự kiện XML khớp với tên loại phần tử đầu tiên (để chụp các phần tử <txn>). Điều này sẽ tạo ra các sự kiện nhỏ (phần tử, thuộc tính, văn bản) có thể được kiểm tra cho các giá trị người dùng phù hợp của bạn. Khi một trận đấu phù hợp, bạn có thể kéo thông tin cần thiết từ các sự kiện hoặc đường ống các sự kiện bị chặn để xây dựng một mini-DOM từ chúng nếu bạn thấy kết quả dễ điều hướng hơn. Nhưng có vẻ như điều đó có thể quá mức nếu đánh dấu đơn giản.

Đây có thể là cách tiếp cận đơn giản nhất, nhanh nhất có thể và tránh được phí trên bộ nhớ của việc xây dựng một DOM. Nếu bạn đã chuyển tên của phần tử và thuộc tính cho bộ lọc (để thuật toán khớp của bạn có thể cấu hình được), bạn có thể làm cho nó tương đối chung chung.

+0

Bạn đã nghe nói về vtd-xml chưa? –

+0

Không cho đến khi bình luận của bạn, không có tôi đã không. Tôi đã tải xuống bản phân phối và sẽ rất vui khi dùng thử. Nó nếu thực hiện như tuyên bố tôi sẽ xem xét sử dụng nó trong môi trường sản xuất, nhưng một trong những hitch tôi thấy inclines tôi hỏi (kể từ khi bạn là tác giả của nó) nếu bạn muốn sẵn sàng cũng phát hành vtd-xml theo một LGPL hoặc Apache giấy phép? Chúng tôi chỉ đơn giản là không thể sử dụng GPL trong môi trường của chúng tôi. Cảm ơn cho tip trong mọi trường hợp. –

+0

Bạn có đang phân phối mã hoặc chỉ sử dụng mã nội bộ không? –

0

Một giải pháp thú vị để xử lý các tệp XML lớn> 10GB.

  1. Sử dụng ANTLR để tạo bù trừ byte cho các phần mà bạn quan tâm. Điều này sẽ tiết kiệm một số bộ nhớ so với cách tiếp cận dựa trên DOM.
  2. Sử dụng JAXB để đọc phần từ vị trí byte

Tìm chi tiết tại ví dụ về wikipedia bãi (17GB) trong này SO trả lời https://stackoverflow.com/a/43367629/1485527

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