2011-01-26 22 views
2

我想構建一個XML文件作爲數據存儲。它應該是這個樣子:如何高效地編寫xml數據庫文件?

<datastore> 
    <item> 
     <subitem></subitem> 
     ... 
     <subitem></subitem> 
    </item> 
    .... 
    <item> 
     <subitem></subitem> 
     ... 
     <subitem></subitem> 
    </item> 
</datastore> 

在運行時,我可能需要將項目添加到數據存儲。項目的數量可能很高,所以我不想將整個文檔放在內存中,也不能使用DOM。我只想寫出發生更改的部分。 還是DOM支持這個?

我有第一次看StAX,但我不知道它是否做我想要的。

就在根元素關閉之前,最好記得文件末尾的光標位置嗎?這總是新的項目將被添加的位置。所以如果我記得那個位置並且在變化過程中保持它的最新狀態,我可以在最後添加一個新的項目,而不必迭代整個文件。

也許第二個遊標可以獨立於第一個遊標使用,爲了讀取目的遍歷文檔。

我看不到StAX支持這一切,是嗎?

是不是有一個基於塊的API文件,而不是一個基礎的流?塊「設備」不是文件和文件系統的典型例子嗎?如果有這樣的API,它能幫我解決我的問題嗎?

在此先感謝。

+0

您是否聽說過vtd-xml和extended vtd-xml?他們來作爲一個罪孽包。 – 2011-01-27 20:05:18

回答

1

更新XML基本上是不可能的,因爲沒有「便宜」的方式來插入數據。

附加XML並不是很糟糕。所有你需要做的就是尋找文件的末尾,然後通過「結束標記」(在這種情況下爲</datastore>)返回,然後開始寫入。這是一個廉價的操作,但是沒有一個框架真的支持這個功能,因爲它們大部分都是設計用於處理格式良好的完整船XML文檔,而不是整體。

您可以使用類似StAX的東西,但在這種情況下,StAX並不知道數據存儲>標記,而是隻知道< item>標記及其元素。然後,您創建Items並開始重複寫入與您已設置的OutputStream相同的內容。

這是做到這一點的最好方法。但如果您需要刪除或更改數據,則可以重寫內容或進行黑客操作,如將元素標記爲「不活動」,在XML文件中查找它們,尋找「active =」Y 「'屬性,然後將Y更改爲N.它可以完成,它將大部分是有效的,但它遠遠超出了常規XML處理框架允許的範圍。如果我這樣做,我會閱讀整個文件並跟蹤這些條目並記下它們的位置,以便稍後我可以輕鬆地查找和更改它們。

然後,當您更新某些內容時,您會「停用」舊內容,然後「追加」新內容。通過全部重寫並拋出舊的「非活動」條目,最終得到GC文件。

+0

有一種便宜的方式來插入數據,超級便宜。 VTD-XML是我現在唯一知道的唯一一個。 – 2011-01-27 20:07:00

1

作爲一個經驗法則,XML文件作爲數據存儲不是非常有效,而不是您希望使用它們的基於記錄的數據。

但是,如果您已經獲得了該文件並且完全無法做任何事情,則可以使用StAX XMLEventReader s和XMLEventWriter快速讀取文件並在其中插入/修改元素。

但是當我說得很快時,我的意思是比DOM更快,但遠不如任何關係數據庫那樣有效。

更新:可以考慮另一種選擇是vtd-xml,雖然我還沒有在實際項目中試了一下,它實際上看起來相當不錯。

0

如果您總是希望在最後添加項目,那麼處理此問題的最佳方法是擁有兩個XML文件。外一個datstore.xml是一個簡單的包裝,看起來像這樣:

<!DOCTYPE datastore [ 
    <!ENTITY e SYSTEM "items.xml"> 
]> 
<datastore>&e;</datastore> 

文件items.xml看起來是這樣的:

<item>....</item> 
<item>....</item> 
<item>....</item> 

沒有包裝元素。

當您想追加數據時,您可以打開items.xml並寫入到它的末尾。當你想讀取數據時,用XML解析器打開datastore.xml。

當然,一旦數據增長超過20Mb左右,最好使用XML數據庫。但是我一直在使用這種方法多年來用於撒克遜命令的記錄,目前大約有8Mb的文件,並且它工作正常。

0

對XML文件進行部分更新並不容易,也不是很有效,因此您不會找到太多支持它的用例。

真的,它聽起來像你需要一個適當的數據庫,也許有一個工具來導出數據爲XML。

如果您不想使用數據庫並堅持將數據純粹存儲爲XML,則可以考慮將所有項目作爲對象保存在內存中。每當添加一個新的時候,你都可以將它們全部寫入XML。這看起來效率不高,但取決於您的數據大小可能仍然足夠好。

如果您選擇此路徑,您可能需要查看Xstream庫以使其變得非常簡單,請參閱stream tutorial以獲得一個簡單示例。