解组 HTML 嵌套在 XML 中
Unmarshal HTML nested in XML
我从第三方收到一个 xml 文件,其中一个 XML 标签中有一个 HTML 元素。我不知道如何解组它以获得 href URL.
XML 示例:
<SOME_HTML>
<a href="http://www.google.com" target="_blank">
google</a>
</SOME_HTML>
这是我到目前为止所了解的,但没有向结构中添加任何内容:
type Href struct {
Link string `xml:"href"`
}
type Link struct {
URL []Href `xml:"a"`
}
type XmlFile struct {
HTMLTag []Link `xml:"SOME_HTML"`
}
myFile := []byte(`<?xml version="1.0" encoding="utf-8"?>
<SOME_HTML>
<a href="http://www.google.com" target="_blank">
google</a>
</SOME_HTML>`)
var output XmlFile
err := xml.Unmarshal(myFile, &output)
fmt.Println(output) // {[]}
你可以这样做 (https://play.golang.org/p/MJzAVLBFfms):
type aElement struct {
Href string `xml:"href,attr"`
}
type content struct {
A aElement `xml:"a"`
}
func main() {
test := `<SOME_HTML><a href="http://www.google.com" target="_blank">google</a></SOME_HTML>`
var result content
if err := xml.Unmarshal([]byte(test), &result); err != nil {
log.Fatal(err)
}
fmt.Println(result)
}
解析 xml 中的所有内容,假设在 html 或其他标签(如 div
)中也可能有多个 a
标签。
如果不需要,只需将 XmlFile.Links
替换为 Link
类型的 XmlFile.Link
(不是 []Link
)
func main() {
type Link struct {
XMLName xml.Name `xml:"a"`
URL string `xml:"href,attr"`
Target string `xml:"target,attr"`
Content string `xml:",chardata"`
}
type Div struct {
XMLName xml.Name `xml:"div"`
Classes string `xml:"class,attr"`
Content string `xml:",chardata"`
}
type XmlFile struct {
XMLName xml.Name `xml:"SOME_HTML"`
Links []Link `xml:"a"`
Divs []Div `xml:"div"`
}
myFile := []byte(`<?xml version="1.0" encoding="utf-8"?>
<SOME_HTML>
<a href="http://www.google.com" target="_blank">google</a>
<a href="http://www.facebook.com" target="_blank">facebook</a>
<div class="someclass">text</div>
</SOME_HTML>`)
var output XmlFile
err := xml.Unmarshal(myFile, &output)
if err != nil {
log.Fatal(err)
}
fmt.Println(output)
}
编辑:在 xml 中添加了更多标签以展示如何解析不同的标签类型。
您可以使用常规 XML 解析器解析您发布的示例,但是 XML 语法有很多例外情况,通常被认为是有效的 HTML。
我能想到的最简单的例子是:我所知道的所有 html 解释器都理解 <br>
(未闭合的 <br>
标签)与自闭合的相同 <br />
标签。
如果您不知道服务另一端的 HTML 是如何生成的,您最好使用 HTML 解析器。
例如,有一个 golang.go/x/net/html
包,它提供了几个函数来解析 HTML :
https://play.golang.org/p/3hUogiwdRPO
func findFirstHref(n *html.Node, indent string) string {
if n.Type == html.ElementNode {
fmt.Println(" * scanning:" + indent + n.Data)
}
if n.Type == html.ElementNode && n.Data == "a" {
for _, a := range n.Attr {
if a.Key == "href" {
return a.Val
}
}
}
for c := n.FirstChild; c != nil; c = c.NextSibling {
href := findFirstHref(c, indent+" ")
if href != "" {
return href
}
}
return ""
}
func main() {
doc1, err := html.Parse(strings.NewReader(sample1))
if err != nil {
fmt.Println(err)
} else {
fmt.Println("href in sample1:", findFirstHref(doc1, ""))
}
doc2, err := html.Parse(strings.NewReader(sample2))
if err != nil {
fmt.Println(err)
} else {
fmt.Println("href in sample2:", findFirstHref(doc2, ""))
}
}
const (
sample1 = `<?xml version="1.0" encoding="utf-8"?>
<SOME_HTML>
<a href="http://www.google.com" target="_blank">
google</a>
</SOME_HTML>`
// sample2 is an invalid XML document (it has unclosed "<br>" tags):
sample2 = `
<p> line1 <br> line2
<a href="foobar" target="_blank">
Some <br> text
</a>
</p>
`
)
我从第三方收到一个 xml 文件,其中一个 XML 标签中有一个 HTML 元素。我不知道如何解组它以获得 href URL.
XML 示例:
<SOME_HTML>
<a href="http://www.google.com" target="_blank">
google</a>
</SOME_HTML>
这是我到目前为止所了解的,但没有向结构中添加任何内容:
type Href struct {
Link string `xml:"href"`
}
type Link struct {
URL []Href `xml:"a"`
}
type XmlFile struct {
HTMLTag []Link `xml:"SOME_HTML"`
}
myFile := []byte(`<?xml version="1.0" encoding="utf-8"?>
<SOME_HTML>
<a href="http://www.google.com" target="_blank">
google</a>
</SOME_HTML>`)
var output XmlFile
err := xml.Unmarshal(myFile, &output)
fmt.Println(output) // {[]}
你可以这样做 (https://play.golang.org/p/MJzAVLBFfms):
type aElement struct {
Href string `xml:"href,attr"`
}
type content struct {
A aElement `xml:"a"`
}
func main() {
test := `<SOME_HTML><a href="http://www.google.com" target="_blank">google</a></SOME_HTML>`
var result content
if err := xml.Unmarshal([]byte(test), &result); err != nil {
log.Fatal(err)
}
fmt.Println(result)
}
解析 xml 中的所有内容,假设在 html 或其他标签(如 div
)中也可能有多个 a
标签。
如果不需要,只需将 XmlFile.Links
替换为 Link
类型的 XmlFile.Link
(不是 []Link
)
func main() {
type Link struct {
XMLName xml.Name `xml:"a"`
URL string `xml:"href,attr"`
Target string `xml:"target,attr"`
Content string `xml:",chardata"`
}
type Div struct {
XMLName xml.Name `xml:"div"`
Classes string `xml:"class,attr"`
Content string `xml:",chardata"`
}
type XmlFile struct {
XMLName xml.Name `xml:"SOME_HTML"`
Links []Link `xml:"a"`
Divs []Div `xml:"div"`
}
myFile := []byte(`<?xml version="1.0" encoding="utf-8"?>
<SOME_HTML>
<a href="http://www.google.com" target="_blank">google</a>
<a href="http://www.facebook.com" target="_blank">facebook</a>
<div class="someclass">text</div>
</SOME_HTML>`)
var output XmlFile
err := xml.Unmarshal(myFile, &output)
if err != nil {
log.Fatal(err)
}
fmt.Println(output)
}
编辑:在 xml 中添加了更多标签以展示如何解析不同的标签类型。
您可以使用常规 XML 解析器解析您发布的示例,但是 XML 语法有很多例外情况,通常被认为是有效的 HTML。
我能想到的最简单的例子是:我所知道的所有 html 解释器都理解 <br>
(未闭合的 <br>
标签)与自闭合的相同 <br />
标签。
如果您不知道服务另一端的 HTML 是如何生成的,您最好使用 HTML 解析器。
例如,有一个 golang.go/x/net/html
包,它提供了几个函数来解析 HTML :
https://play.golang.org/p/3hUogiwdRPO
func findFirstHref(n *html.Node, indent string) string {
if n.Type == html.ElementNode {
fmt.Println(" * scanning:" + indent + n.Data)
}
if n.Type == html.ElementNode && n.Data == "a" {
for _, a := range n.Attr {
if a.Key == "href" {
return a.Val
}
}
}
for c := n.FirstChild; c != nil; c = c.NextSibling {
href := findFirstHref(c, indent+" ")
if href != "" {
return href
}
}
return ""
}
func main() {
doc1, err := html.Parse(strings.NewReader(sample1))
if err != nil {
fmt.Println(err)
} else {
fmt.Println("href in sample1:", findFirstHref(doc1, ""))
}
doc2, err := html.Parse(strings.NewReader(sample2))
if err != nil {
fmt.Println(err)
} else {
fmt.Println("href in sample2:", findFirstHref(doc2, ""))
}
}
const (
sample1 = `<?xml version="1.0" encoding="utf-8"?>
<SOME_HTML>
<a href="http://www.google.com" target="_blank">
google</a>
</SOME_HTML>`
// sample2 is an invalid XML document (it has unclosed "<br>" tags):
sample2 = `
<p> line1 <br> line2
<a href="foobar" target="_blank">
Some <br> text
</a>
</p>
`
)