處理 XML

lua-users home
wiki

處理 XML 樹的迭代器

(這是 LazyKit 的一部分。)

請參閱 XmlIter 以了解這些函數的非處理版本。

xpairs_c(tree)xnpairs_c(tree)xmliter.switch_c(parent, ftable, [opts]) 也會迭代處理 tree 的子項,但它們在處理時會處理 tree 的子項。以下兩個區段具有相似的語意

for i,x in xpairs(parent) do
  parent[i] = nil
  do_something_with(x)
end

for i,x in xpairs_c(parent) do
  do_something_with(x)
end 

使用處理迭代器表示您不在乎透過父層存取先前處理的樹。但是,您仍可以儲存目前的樹以供之後使用

for i,x,name in xnpairs(parent) do
  if x.name == "xref" then
    table.insert(references, x)
  end
end 

使用處理迭代器的主要原因是減少記憶體使用量。在使用傳統的 XML 樹時,如果您在分解 XML 樹的同時建立另一個資料結構,這可能會有些幫助;您已經處理的樹的部分符合垃圾回收的資格,因此為新的結構節省了空間。

然而,在使用 LazyTree XML 樹時,記憶體使用量可以變得極為小。考慮處理一個大型記錄檔

<log>
  <entry>[....]</entry>
  <entry>[....]</entry>
  [...millions of elements later...]
  <entry>[....]</entry>
</log> 

對於傳統 XML 樹,處理這個記錄檔需要與所有 <entry> 元素大小成線性比例的空間。對於常規迭代器和延伸樹,則需要與之前處理的所有 <entry> 元素成線性比例的空間(因為未來的元素僅會根據需求讀取)。對於處理迭代器和延伸樹,處理僅需要與單一 <entry> 元素大小成比例的空間,因為之前處理的 <entry> 已被遺忘。

使用處理迭代器的次要好處是它們可能會減少少量 CPU 的使用。當存在較少的活動資料時,Lua 5.0 垃圾回收器在回收期間不必工作得這麼辛苦。(??? 重新閱讀 GC 演算法以確保這是真的,儘管有定時數字。)

這裡真正發生的是迭代器會提供一個事件為基礎的介面至資料表。處理迭代器會提供許多與純粹事件為基礎的 XML 解析器相同的好處,同時也讓您在有意義的情況下流暢地切換回基於樹的 API。

一個具體的範例是 XML-RPC <value> 節點。如果它們包含如 <integer> 等的元素,這就是 <value> 節點的值。否則,<value> 元素的字元資料內容就是字串型別的值。處理元素的程式碼可能會潛在先檢視任意數量的初始字元資料節點,以找出裡面是否潛藏著元素,否則就必須預設為字串內容。事件為基礎策略可以將元素的子項清單視為一個任意長度的先期緩衝。

使用提示

將處理迭代器替換為非處理迭代器永遠都是安全的;後果可能只有在處理大型文件時,記憶體耗盡。

它用一個消耗迭代器,只在處理樹狀結構的最後一步才最有意義。因為 XML 樹狀結構是延遲的執行方式,所以觸動子節點在呼叫消耗迭代器之前並不會發生錯誤。

在遞迴處理元素時,只有在你確定呼叫者不再需要其內容時,才應該呼叫一個消耗迭代器。一個經驗法則是:只在另一個消耗迭代器內呼叫消耗迭代器。


最近變更 · 偏好設定
編輯 · 歷史紀錄
上次編輯時間為 2004 年 2 月 29 日上午 12:34 GMT (diff)