亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

獲取原始元素表示,包括開始和結束標簽

獲取原始元素表示,包括開始和結束標簽

Go
至尊寶的傳說 2023-07-31 17:34:39
我知道 golang xml,innerxml標簽,它允許將元素內部內容作為原始 xml 獲取。但我需要的是獲取整個元素(開放標簽、內部內容、關閉標簽)作為原始數據。這是一個我想以這種方式解析的示例。我想獲得整體<Useful>及其所有可能的屬性元素,并避免獲得無用的元素。package mainimport (    "encoding/xml"    "fmt")const data = `<Document>    <Useless1>        blah-blah    </Useless1>    <Useless2>        blah-blah    </Useless2>    <Useful someAttr="someVal">        <InnerField1>Inner field 1 value</InnerField1>        <InnerField2>Inner field 2 value</InnerField2>        <InnerField3>Inner field 3 value</InnerField3>    </Useful>    <Useless3>        blah-blah    </Useless3></Document>`func main() {    doc := Document{}    err := xml.Unmarshal([]byte(data), &doc)    if err != nil {        panic(err)    }    fmt.Println(doc.Useful.Data)}type Document struct {    XMLName xml.Name `xml:"Document"`    Useful  struct {        Data string `xml:",innerxml"`    } `xml:"Useful"`}游樂場中代碼的鏈接位于: https: //goplay.space/#0KDXiRKDwlY這就是我得到的:    <InnerField1>Inner field 1 value</InnerField1>     <InnerField2>Inner field 2 value</InnerField2>     <InnerField3>Inner field 3 value</InnerField3>這就是我想要得到的:<Useful someAttr="someVal">     <InnerField1>Inner field 1 value</InnerField1>     <InnerField2>Inner field 2 value</InnerField2>     <InnerField3>Inner field 3 value</InnerField3></Useful>請注意,我正在使用的實際結構要復雜得多。我不想將整個<Document>內部內容作為原始 xml 獲取,然后對其進行解析,嘗試手動刪除無用的元素。該<Useful>部分各不相同,因此我無法對例如屬性進行硬編碼,因為它們可能因一個文檔而異。
查看完整描述

1 回答

?
料青山看我應如是

TA貢獻1772條經驗 獲得超8個贊

也捕獲屬性

您可以在結構中使用附加字段Useful來捕獲(類型切片的xml.Attr)所有屬性,如下所示:

Useful? struct {

? ? Attrs []xml.Attr `xml:",any,attr"`

? ? Data? string? ? ?`xml:",innerxml"`

} `xml:"Useful"`

添加另一個屬性時<Useful>:


<Useful someAttr="someVal" someAttr2="someVal2">

? ? ...

<Useful>

并使用 輸出結果fmt.Printf("%+v", doc.Useful),輸出將是(在Go Playground上嘗試一下):

{Attrs:[{Name:{Space:?Local:someAttr}?Value:someVal}?{Name:{Space:?Local:someAttr2}?Value:someVal2}]?Data:
????????<InnerField1>Inner?field?1?value</InnerField1>
????????<InnerField2>Inner?field?2?value</InnerField2>
????????<InnerField3>Inner?field?3?value</InnerField3>
????}

真正獲得完整的原始 XML

另一種更復雜的方法是使用xml.Decoder標記讀取輸入,并標記 的開始和結束位置<Useful>。然后你就可以獲得完整的原始XML?<Useful>。

它可能是這樣的:

dec := xml.NewDecoder(strings.NewReader(data))


var start, end int64

foundStart := false

for {

? ? if !foundStart {

? ? ? ? start = dec.InputOffset()

? ? }

? ? t, err := dec.Token()

? ? if err != nil {

? ? ? ? if err != io.EOF {

? ? ? ? ? ? fmt.Println(err)

? ? ? ? }

? ? ? ? break

? ? }

? ? if se, ok := t.(xml.StartElement); ok {

? ? ? ? if se.Name.Local == "Useful" {

? ? ? ? ? ? foundStart = true

? ? ? ? }

? ? }

? ? if se, ok := t.(xml.EndElement); ok {

? ? ? ? if se.Name.Local == "Useful" {

? ? ? ? ? ? end = dec.InputOffset()

? ? ? ? ? ? // We may break here, we got what we wanted

? ? ? ? ? ? break

? ? ? ? }

? ? }

}


fmt.Println(data[start:end])

它輸出(在Go Playground上嘗試):


<Useful someAttr="someVal" someAttr2="someVal2">

? ? ? ? <InnerField1>Inner field 1 value</InnerField1>

? ? ? ? <InnerField2>Inner field 2 value</InnerField2>

? ? ? ? <InnerField3>Inner field 3 value</InnerField3>

? ? </Useful>

由于我們不處理 的內容,因此我們可以通過如下<Useful>使用來加快速度:Decoder.Skip()

dec := xml.NewDecoder(strings.NewReader(data))


var start, end int64

for {

? ? start = dec.InputOffset()

? ? t, err := dec.Token()

? ? if err != nil {

? ? ? ? if err != io.EOF {

? ? ? ? ? ? fmt.Println(err)

? ? ? ? }

? ? ? ? break

? ? }

? ? if se, ok := t.(xml.StartElement); ok {

? ? ? ? if se.Name.Local != "Useful" {

? ? ? ? ? ? continue

? ? ? ? }

? ? ? ? if err := dec.Skip(); err != nil {

? ? ? ? ? ? fmt.Println(err)

? ? ? ? ? ? break

? ? ? ? }

? ? ? ? end = dec.InputOffset()

? ? ? ? break

? ? }

}


fmt.Println(data[start:end])

輸出是一樣的。在Go Playground上試試這個。




查看完整回答
反對 回復 2023-07-31
  • 1 回答
  • 0 關注
  • 176 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號