2010-04-16 21 views
6

Cập nhật Không có trình phân tích cú pháp XML sẵn sàng trong cộng đồng Java có thể thực hiện phân tích cú pháp NIO và XML. Đây là gần nhất tôi tìm thấy, và nó không đầy đủ: http://wiki.fasterxml.com/AaltoHomeXMLStreamReader và một luồng thực

Tôi có đoạn mã sau:

InputStream input = ...; 
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance(); 

XMLStreamReader streamReader = xmlInputFactory.createXMLStreamReader(input, "UTF-8"); 

Câu hỏi là, tại sao #createXMLStreamReader() phương pháp hy vọng sẽ có toàn bộ một tài liệu XML trong đầu vào suối? Tại sao nó được gọi là "trình đọc luồng", nếu nó dường như không thể xử lý một phần dữ liệu XML? Ví dụ: nếu tôi cho nguồn cấp dữ liệu:

<root> 
    <child> 

cho nó, nó sẽ cho tôi biết tôi đang thiếu thẻ đóng. Ngay cả trước khi tôi bắt đầu lặp lại chính trình đọc luồng. Tôi nghi ngờ rằng tôi không biết cách sử dụng XMLStreamReader đúng cách. Tôi có thể cung cấp dữ liệu theo từng phần, đúng không? Tôi cần nó vì tôi đang xử lý một luồng XML đến từ ổ cắm mạng và không muốn tải toàn bộ văn bản nguồn vào bộ nhớ.

Cảm ơn bạn đã trợ giúp, Yuri.

Trả lời

1

Nếu bạn hoàn toàn cần NIO với nội dung "đẩy", có các nhà phát triển quan tâm đến việc hoàn thành API cho Aalto. Trình phân tích cú pháp chính nó là hoàn thành việc thực hiện Stax cũng như thay thế "đầu vào đẩy" (nạp đầu vào thay vì sử dụng InputStream). Vì vậy, bạn có thể muốn kiểm tra danh sách gửi thư nếu bạn quan tâm. Không phải ai cũng đọc câu hỏi StackOverflow. :-)

1

Luồng phải chứa nội dung cho toàn bộ tài liệu XML, không phải tất cả trong bộ nhớ cùng một lúc (đây là những gì luồng làm). Bạn có thể giữ luồng và trình đọc mở để tiếp tục cho ăn trong nội dung; tuy nhiên, nó sẽ phải là một phần của một tài liệu XML được định dạng tốt.

Gợi ý: Bạn có thể muốn đọc thêm một chút về cách hoạt động của ổ cắm và luồng trước khi đi xa hơn.

Hy vọng điều này sẽ hữu ích.

+1

Có, luồng có khả năng phải chứa toàn bộ tài liệu. Nhưng tại sao XMLStreamReader nên thử xác nhận tất cả nó lên phía trước? Đó là một dòng suối. Tại sao nó không thể đi cùng với dữ liệu và phân tích cú pháp những gì có sẵn? Và * nếu * nó gặp một lỗi, tôi sẽ tự xử lý nó. Đúng nếu tôi sai - bạn đang nói rằng nếu tôi đang đọc tài liệu XML có dung lượng 1 gigabyte trên mạng, tôi nên tải xuống tất cả và chỉ khi đó XMLStreamReader mới có thể lặp lại nó? –

+0

Tôi nghĩ rằng nó sẽ không xác nhận cho đến khi toàn bộ luồng đã được xử lý (và đóng). Bạn không cần phải tải về toàn bộ điều đó, đó là những gì suối cho. Bạn đang viết thư cho luồng rồi đóng rồi cố gắng viết thêm? – cjstehno

+0

Yuri, không, trình phân tích cú pháp Stax sẽ KHÔNG đọc nó hoàn toàn trước tiên; bạn chắc chắn có thể bắt đầu đọc ngay lập tức và trình phân tích cú pháp sẽ chỉ chặn nếu nó chưa có bất kỳ dữ liệu nào để phân tích cú pháp. Tôi không biết vấn đề là gì, nhưng sự hiểu biết của bạn là chính xác. – StaxMan

-2

Nhìn vào liên kết này để hiểu thêm về cách hoạt động của trình phân tích cú pháp phát trực tuyến và cách nó giữ cho bạn in chân bộ nhớ r nhỏ hơn. Đối với XML đến, trước tiên bạn cần phải tuần tự hóa XML đến và tạo một XML được định dạng tốt, sau đó đưa nó vào trình phân tích cú pháp phát trực tuyến.

http://www.devx.com/xml/Article/34037/1954

0

Bạn đang sử dụng phiên bản Java nào? Với JDK 1.6.0_19, tôi nhận được hành vi mà bạn mong đợi. Iterating trên đoạn XML ví dụ của bạn mang lại cho tôi ba sự kiện:

  • START_ELEMENT (root)
  • ký tự (khoảng trắng giữa và)
  • START_ELEMENT (con)

Các invokation IV tiếp theo() ném một XMLStreamException: ParseError tại [row, col]: [2,12] Thông báo: Cấu trúc tài liệu XML phải bắt đầu và kết thúc trong cùng một thực thể.

+0

Điều này cũng giống như những gì Woodstox làm là tốt. Câu hỏi là sai trong ngụ ý khác. – StaxMan

2

Bạn có thể nhận được những gì bạn muốn - một phần phân tích cú pháp, nhưng bạn không được đóng luồng khi bạn đến cuối dữ liệu hiện có. Giữ luồng mở và trình phân tích cú pháp sẽ đơn giản chặn khi nó đến cuối luồng. Khi bạn có nhiều dữ liệu hơn, hãy thêm dữ liệu đó vào luồng và trình phân tích cú pháp sẽ tiếp tục.

Sắp xếp này yêu cầu hai luồng - một chuỗi chạy trình phân tích cú pháp và một dữ liệu tìm nạp khác. Để nối hai luồng, bạn sử dụng một đường ống - một cặp PipeInputStream và PipeOutputStream đẩy dữ liệu từ luồng trình đọc vào luồng đầu vào được trình phân tích cú pháp sử dụng. (Trình phân tích cú pháp đang đọc dữ liệu từ PipeInputStream.)

+0

Tôi nên làm rõ rằng việc chặn không phải là một lựa chọn trong trường hợp của tôi. Khi không có thêm dữ liệu để đọc (tại lời gọi hiện tại) trình phân tích cú pháp sẽ xử lý nó như tình huống bình thường và cung cấp cho tôi bất kỳ dữ liệu nào được phân tích cú pháp từ dữ liệu một phần. –

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