GoLang解析XML,非Unmarshal方法

2021-10-10 04:12:37 字數 1776 閱讀 4051

看網上好多都是用的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 即 時 ...