2011-10-12 39 views
6

Tôi có vấn đề sau: Tôi có các tệp XML rất lớn (như 300+ Megs) và tôi cần phân tích chúng để thêm một số giá trị của chúng vào db. Cấu trúc của các tệp này cũng rất phức tạp. Tôi muốn sử dụng Stax Parser vì nó cung cấp khả năng kéo-phân tích cú pháp (và do đó xử lý) chỉ một phần của tệp XML tại một thời điểm, và do đó không tải toàn bộ điều trong bộ nhớ, nhưng mặt khác nhận được các giá trị với Stax (ít nhất là trên các tập tin XML) là cồng kềnh, tôi cần phải viết một tấn mã. Từ quan điểm sau này, nó sẽ vô cùng giúp tôi nếu tôi có thể sắp xếp tệp XML thành các đối tượng Java (như JAX-B), tuy nhiên điều này sẽ tải toàn bộ tệp cùng với một tấn các cá thể Object trong bộ nhớ cùng một lúc.Phân tích cú pháp các tệp XML rất lớn và marshalling đối tượng Java

Câu hỏi của tôi là, có cách nào để phân tích cú pháp (hoặc phân tích cú pháp một phần) tập tin tuần tự, và sau đó chỉ sửa đổi các phần đó với đối tượng Java để tôi có thể xử lý chúng một cách dễ dàng mà không bị bẻ khóa trên bộ nhớ?

Trả lời

2

Vâng, trước hết tôi muốn cảm ơn hai người trả lời câu hỏi của tôi, nhưng cuối cùng tôi đã kết thúc không sử dụng những mệnh đề một phần là do những công nghệ đề xuất là một chút xa Java hãy nói "phân tích cú pháp XML chuẩn" và nó cảm thấy kỳ lạ khi có một công cụ tương tự đã có trong Java và một phần cũng bởi vì trên thực tế tôi đã tìm ra một giải pháp chỉ sử dụng Java API để thực hiện điều này.

Tôi sẽ không chi tiết quá nhiều giải pháp tôi tìm thấy, bởi vì tôi đã hoàn thành việc triển khai và nó là một đoạn mã lớn để đặt ở đây (tôi sử dụng Spring Batch trên đầu trang tất cả, với một tấn cấu hình và nội dung).

tôi tuy nhiên sẽ làm cho một lời nhận xét nhỏ về những gì cuối cùng tôi đã kết thúc thực hiện:

Ý tưởng lớn ở đây là một thực tế rằng nếu bạn có một tài liệu XML VÀ nó giản đồ XSD tương ứng, bạn có thể phân tích & marshall nó với JAXB, và bạn có thể làm điều đó trong các khối, và nói rằng các khối có thể được đọc với một trình phân tích cú pháp thậm chí như STAX và sau đó được chuyển tới JAXB Marshaller. Điều này thực tế có nghĩa là trước tiên bạn phải quyết định nơi nào là một nơi tốt trong tệp XML của bạn, nơi bạn có thể nói "phần này ở đây có rất nhiều cấu trúc lặp lại, tôi sẽ xử lý những lần lặp lại một lần". Những phần lặp đi lặp lại thường là cùng một thẻ (con) lặp đi lặp lại rất nhiều bên trong một thẻ cha. Vì vậy, tất cả những gì bạn phải làm là tạo một trình lắng nghe sự kiện trong trình phân tích cú pháp STAX của bạn được kích hoạt ở đầu mỗi thẻ con đó, hơn là truyền JAXB nội dung của thẻ con đó, kết hợp nó với JAXB và xử lý nó. Thực sự ý tưởng được mô tả tuyệt vời trong bài viết này, mà tôi theo sau (đúng, nó là từ năm 2006, nhưng nó đề cập đến JDK 1.6 vào thời điểm đó là khá mới, vì vậy phiên bản khôn ngoan không phải là cũ):

http://www.javarants.com/2006/04/30/simple-and-efficient-xml-parsing-using-jaxb-2-0/

+0

Tốt để biết prob của bạn được giải quyết. Chỉ cần tự hỏi làm thế nào là điều này (soln trong bài đăng này) khác với những gì tôi đã đăng? – Kashyap

+0

Vâng, trung thực nó là một phần lo sợ của các khuôn khổ lớn, một phần lười biếng :) (cả hai đều là xấu và đáng tiếc). Trước hết, từ tài liệu EMF có vẻ như là một khung công tác khá liên quan, nó không chỉ dành cho việc xử lý XML mà còn cho rất nhiều thứ khác, và tôi luôn cố gắng tránh những khung công tác nặng nề bất cứ khi nào có thể (đây chỉ là sở thích cá nhân, nói là xấu để làm điều đó nói chung). Thứ hai, tôi lười biếng, và EMF sử dụng các API phân tích cú pháp XML không chuẩn mà tôi cũng không biết vì điều này tôi đã sử dụng giải pháp này với các API Java XML chuẩn. –

+1

Thật vậy, cho dù bạn có thích EMF hay không, tôi khuyên KHÔNG nên sử dụng nó ("** vì EMF là một cái búa quá lớn cho một vấn đề nhỏ như vậy. **") trừ khi bạn không có lựa chọn. Và abt phân tích cú pháp, để trích dẫn một lần nữa "vì vậy ** chỉ phân tích bằng cách sử dụng bất cứ điều gì bạn muốn **, tạo một số StringStream hoặc một cái gì đó cho mỗi trong một vòng lặp và ** vượt qua để JAX-B hoặc EMF. **" – Kashyap

5

Tôi muốn giới thiệu Eclipse EMF. Nhưng nó có cùng một vấn đề, nếu bạn đặt tên cho nó, nó sẽ phân tích toàn bộ nội dung. Mặc dù có một số tùy chọn để giảm số lượng được tải, nhưng tôi không bận tâm nhiều khi chúng tôi chạy trên máy có RAM 96 GB. :)

Dù sao, nếu định dạng XML của bạn được xác định rõ, thì một cách giải quyết là đánh lừa EMF bằng cách chia nhỏ toàn bộ tệp thành nhiều đoạn mã XML nhỏ hơn (nhưng vẫn được xác định rõ). Sau đó, mỗi nguồn cấp dữ liệu từng đoạn mã một. Tôi không biết JAX-B, nhưng có lẽ cách giải quyết tương tự cũng có thể được áp dụng ở đó. Mà tôi muốn giới thiệu, bởi vì EMF là một cái búa quá lớn cho một vấn đề nhỏ như vậy.

Chỉ cần để xây dựng một chút nếu XML của bạn trông như thế này:

<tag1> 
    <tag2> 
     <tag3/> 
     <tag4> 
      <tag5/> 
     </tag4> 
     <tag6/> 
     <tag7/> 
    </tag2> 

    <tag2> 
     <tag3/> 
     <tag4> 
      <tag5/> 
     </tag4> 
     <tag6/> 
     <tag7/> 
    </tag2> 
............ 
    <tag2> 
     <tag3/> 
     <tag4> 
      <tag5/> 
     </tag4> 
     <tag6/> 
     <tag7/> 
    </tag2> 
</tag1> 

Sau đó, nó có thể được chia nhỏ thành một XML từng bắt đầu với <tag2> và kết thúc với </tag2>. Và trong java hầu hết các trình phân tích cú pháp sẽ chấp nhận một luồng, do đó, chỉ cần phân tích bằng cách sử dụng bất cứ điều gì bạn muốn, tạo một số StringStream hoặc một cái gì đó cho mỗi <tag2> trong một vòng lặp và chuyển đến JAX-B hoặc EMF.

HTH

+0

Đây là điều tuyệt vời và tôi sẽ thử điều đầu tiên vào ngày mai (bây giờ là nửa đêm ở đây :)). Cảm ơn đề xuất, âm thanh đầy hứa hẹn –

+1

@thekashyap. Tôi có thể có một trong những cái máy đó không, plesae? Chỉ một! –

+0

Hehe .. Đó là những máy thử nghiệm của chúng tôi, ở nhà tôi làm việc trên một máy tính xách tay Win7 với 4GB như mọi người khác .. :) – Kashyap

1

Chiếu tài liệu có thể là câu trả lời ở đây. Saxon và một số bộ xử lý XQuery khác cung cấp tùy chọn này. Nếu bạn có truy vấn đơn giản hợp lý chọn một lượng nhỏ dữ liệu từ tài liệu lớn, bộ xử lý truy vấn sẽ phân tích truy vấn để tìm ra phần nào của cây cần có sẵn cho truy vấn và có thể bị loại bỏ trong quá trình xử lý. Cây kết quả thường có thể chỉ bằng 1% kích thước của tài liệu đầy đủ. Chi tiết cho Saxon ở đây:

http://saxonica.com/documentation/sourcedocs/projection.xml

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