看網上好多都是用的unmarshal函式,但是對於有些不知道節點數量的情況,unmarshal函式還是無法很好完成。所以自己寫了個方法,在這裡記下來,免得忘了。
package loader
import (
"encoding/xml"
"errors"
"fmt"
"io"
"strings"
)// node xml的節點結構體
type node struct
// printnode 在控制台輸出節點左右資訊
func (node *node) printnode()
} if node.parentnode == nil else
childnodes := node.childnodes
if len(childnodes) != 0 }}
// stack 用來壓入xml的節點。
type stack struct
func (s *stack) push(node *node) error
s.top++
s.arr[s.top] = node
return nil
}func (s *stack) pop() (node *node, err error)
node = s.arr[s.top]
s.top--
return node, nil
}func (s *stack) topvalue() *node
func initstack(maxtop, top int) *stack
}// loadxml 通過檔案路徑載入xml,並返回解析的節點鏈
func loadxml(xmldec *xml.decoder) (root *node, err error)
if err != nil
// 判斷節點型別
switch t := token.(type)
}if s.top == -1 else
previousnode := s.topvalue()
node.parentnode = previousnode
// 只有在非根節點的開始元素載入時才會設定為true
startelementloaded = true
s.push(node)
}// 將值存入節點鏈中最後乙個節點
case xml.chardata:
// 根節點後面的換行符會被識別為xml.chardata型別,currentnode還沒有被例項化,
// 此時向currentnode寫入值會產生panic,所以在此處要做乙個非nil的判斷
if node != nil
}// 結束標籤,主要將當前標籤名彈出棧
case xml.endelement:
startelementloaded = false
s.pop()
// comment,procinst和directive型別的內容不做處理
case xml.comment:
case xml.procinst:
case xml.directive:
default:
panic(errors.new("parse failed"))
} }return
}
這樣在獲得節點鏈之後,就可以按自己的需求進行處理了。
ps:之前版本寫得太爛,重新修改了一下。單元測試和基準測試的**在下面。
golang 解析XML帶動態屬性
很顯然,上面一段xml檔案可以看出,item中屬性名不同,但是在定義結構體的時候,解析dataset 時候只能定義成切片,所以只能把 ttem中的屬性弄成動態屬性,如下。attributes xml.attr xml any,attr package main import encoding xml...
非遞迴(棧)演算法解析XML思路
對於樹狀層次結構的資料,往往有兩種處理思路 遞迴演算法處理和非遞迴 棧 演算法處理。遞迴演算法 簡單易懂,且有些場景還必須使用遞迴演算法才能處理。但遞迴演算法也有其先天性的缺陷 執行效率較低 執行過程所耗費的空間資源也相對較高。非遞迴 棧 演算法 演算法相對比較複雜,不太好理解,但其執行效率較高。以...
iPhone解析非UTF 8的XML
做iphone的網路應用,處理xml是家常便飯,nsxmlparser用起來還是得心應手的。不過這個東西,處理非utf 8,會解析失敗。這篇文章就是想和大家一起分享一些這方面開發的新的。我們在某個rss位址,可以得到下面這樣的xml檔案。我這裡只是擷取一段,rthk on internet 即 時 ...