gpt4 book ai didi

xml - 获取原始元素表示,包括开始和结束标签

转载 作者:行者123 更新时间:2023-12-02 12:04:03 26 4
gpt4 key购买 nike

我了解 golang xml ,innerxml标签允许以原始 xml 形式获取元素内部内容。但我需要的是获取整个元素(开放标签、内部内容、关闭标签)作为原始数据。

这是一个我想以这种方式解析的示例。我想要完整的<Useful>包含所有可能的属性元素并避免获得无用的元素。

package main

import (
"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"`
}

Playground 中代码的链接在这里: 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>部分有所不同,所以我无法硬编码,例如属性导致它们在不同文档之间可能有所不同。

最佳答案

也捕获属性

您可以在 Useful 中使用附加字段struct 来捕获所有属性(类型为 xml.Attr 的 slice ),如下所示:

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 通过token读取输入,并标记<Useful>的开始和结束位置。然后你就可以获得<Useful>的完整原始XML .

它可能是这样的:

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 .

关于xml - 获取原始元素表示,包括开始和结束标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58765192/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com