2010-04-16 18 views
6

更新在Java社區沒有準備好的XML解析器可以執行NIO和XML解析。這是我發現的最接近,這是不完整的:http://wiki.fasterxml.com/AaltoHomeXMLStreamReader和一個真正的流

我有以下代碼:

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

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

的問題是,爲什麼法#createXMLStreamReader()預計將有一個完整的XML文檔中輸入流?爲什麼它稱爲「流式閱讀器」,如果它似乎無法處理一部分XML數據?例如,如果我喂:

<root> 
    <child> 

它,它會告訴我我錯過了結束標籤。甚至在我開始迭代流讀取器本身之前。我懷疑我只是不知道如何正確使用XMLStreamReader。我應該能夠提供數據的部分,對不對?我需要它,因爲我正在處理從網絡套接字傳入的XML流,並且不想將整個源文本加載到內存中。

謝謝你的幫助, 尤里。

回答

1

如果您絕對需要內容爲「推送」的NIO,那麼有開發人員有興趣爲Aalto完成API。解析器本身是完整的Stax實現以及替代的「推入輸入」(饋送輸入而不是使用InputStream)。所以如果你感興趣的話,你可能會想看看郵件列表。並非所有人都閱讀StackOverflow問題。 :-)

1

流必須包含整個XML文檔的內容,而不是全部同時在內存中(這是流所做的)。您可能能夠保持流和讀者開放,繼續提供內容;但是,它必須是格式良好的XML文檔的一部分。

建議:您可能想更詳細地瞭解套接字和數據流如何在更遠的地方工作。

希望這會有所幫助。

+1

是的,潛在的流必須包含整個文檔。但爲什麼XMLStreamReader會試圖驗證所有這一切?這是一個流。爲什麼不能隨數據一起去解析任何可用的數據?如果*遇到錯誤,我會自己處理。 糾正我,如果我錯了 - 你是說如果我通過網絡讀取1千兆字節大小的XML文檔,我應該全部下載並且只有XMLStreamReader才能夠迭代它呢? – 2010-04-16 15:19:25

+0

我會認爲它不會驗證,直到整個流已被處理(和關閉)。你不應該下載整個事情,那是什麼流。你是否正在寫信給該流,然後關閉它,然後嘗試寫更多? – cjstehno 2010-04-16 15:59:36

+0

Yuri,不,Stax解析器不會完全讀取它;您肯定可以立即開始閱讀,並且解析器只會在沒有任何數據解析的情況下才會被阻止。我不知道問題是什麼,但你的理解是正確的。 – StaxMan 2010-10-02 00:35:41

-2

查看此鏈接,瞭解有關流式解析器如何工作的更多信息,以及它如何讓您的內存足跡更小。對於傳入的XML,您需要首先序列化傳入的XML並創建一個格式良好的XML,然後將其傳遞給流式解析器。

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

0

您正在使用哪個Java版本?使用JDK 1.6.0_19,我得到了您似乎期待的行爲。遍歷您的示例XML片段,給了我三個事件:

  • START_ELEMENT(根)
  • 字符(之間的空白和)
  • START_ELEMENT(孩子)

接下來的第四invokation()在[row,col]拋出XMLStreamException:ParseError:[2,12] 消息:XML文檔結構必須在同一個實體中開始和結束。

+0

這與Woodstox所做的一樣。否則,暗示問題是錯誤的。 – StaxMan 2010-10-02 00:34:12

2

你可以得到你想要的 - 部分解析,但是當你到達當前可用數據的末尾時,你不能關閉該流。保持流打開,當分析器到達流的末尾時,它將簡單地阻塞。當你有更多的數據,然後將它添加到流中,解析器將繼續。

這種安排需要兩個線程 - 一個線程運行解析器,另一個線程獲取數據。爲了連接這兩個線程,可以使用一個管道 - 一個PipeInputStream和PipeOutputStream對,它將讀取器線程的數據推送到解析器使用的輸入流中。 (解析器正在從PipeInputStream讀取數據。)

+0

我應該澄清,在我的情況下阻止不是一種選擇。當沒有更多的數據可供閱讀時(目前的調用),解析器應該像正常情況那樣對待它,並向我提供從部分數據中解析出來的任何數據。 – 2011-02-10 08:12:13