我正在尝试解析Go中的XML:
package main
import (
"encoding/xml"
"fmt"
)
type XML struct {
Foo string `xml:"foo"`
}
func main() {
rawXML := []byte(`
<xml>
<foo>A</foo>
<ns:foo>B</ns:foo>
</xml>`)
x := new(XML)
xml.Unmarshal(rawXML, x)
fmt.Printf("foo: %s\n", x.Foo)
}
输出:
foo: B
虽然我预计会产生:
foo: A
如何获取第一个foo
标记的内容(即没有名称空间的标记)?
答案 0 :(得分:5)
我认为xml解码器不能指定一个元素应该没有带有struct标签的命名空间。但我知道它可以为您检索有关命名空间的信息,然后您可以在之后处理数据以获得相同的结果:
package main
import (
"encoding/xml"
"fmt"
)
type Foo struct {
XMLName xml.Name
Data string `xml:",chardata"`
}
type XML struct {
Foo []Foo `xml:"foo"`
}
func main() {
rawXML := []byte(`
<xml>
<foo>A</foo>
<ns:foo>B</ns:foo>
</xml>`)
x := new(XML)
xml.Unmarshal(rawXML, x)
//fmt.Printf("foo: %#v\n", x)
for _, el := range x.Foo {
if el.XMLName.Space == "" {
fmt.Printf("non namespaced foo %q", el.Data)
}
}
}
答案 1 :(得分:4)
xml文档中有两个串联值。您的结构中只有一个值的空间。 xml解析器正在解析第一个,然后用第二个覆盖它。
将Foo更改为结构中的切片,然后您将获得两个值。
http://play.golang.org/p/BRgsuMQ7rK
package main
import (
"encoding/xml"
"fmt"
)
type XML struct {
Foo []string `xml:"foo"`
}
func main() {
rawXML := []byte(`
<xml>
<foo>A</foo>
<ns:foo>B</ns:foo>
</xml>`)
x := new(XML)
xml.Unmarshal(rawXML, x)
fmt.Printf("foo: %s\n", x.Foo[0])
fmt.Printf("both: %v\n", x.Foo)
}
答案 2 :(得分:0)
xml:"foo"
选择器语法采用了可选的命名空间xml:"ns foo"
,但问题是它不支持选择无命名空间的方法。
一种解决方法是使用xml.Decoder.DefaultSpace
来简单地为未命名的标签分配一个名称空间,您现在可以使用xml:"<ns> <tag>"
语法选择该标签:
https://play.golang.org/p/1UggvqLFT9x
import (
"encoding/xml"
"strings"
"fmt"
)
type Doc struct {
Foo string `xml:"_ foo"` // <-- <foo> will now be <_:foo>
NsFoo string `xml:"ns foo"`
}
var input = `<xml>
<foo>A</foo>
<ns:foo>B</ns:foo>
</xml>`
func main() {
decoder := xml.NewDecoder(strings.NewReader(input))
decoder.DefaultSpace = "_"
doc := &Doc{}
decoder.Decode(doc)
fmt.Printf("<foo>: %#v\n", doc.Foo)
fmt.Printf("<ns:foo>: %#v\n", doc.NsFoo)
}
打印:
<foo>: A
<ns:foo>: B