假设https://www.notre-shop.com/sitemap_products_1.xml我有一个xml文件,我想在我的go代码中解组这个xml所以我这样做了
package main
import (
"encoding/xml"
"fmt"
"io/ioutil"
"log"
"net/http"
)
var Product struct {
Locs []string `xml:"url>loc"`
Name []string `xml:"url>image:title"`
}
func main() {
res, err := http.Get("https://www.notre-shop.com/sitemap_products_1.xml")
if err!=nil{
log.Fatal(err)
}
data, err := ioutil.ReadAll(res.Body)
if err!=nil{
log.Fatal(err)
}
defer res.Body.Close()
err = xml.Unmarshal(data, &Product)
if err!=nil{
log.Fatal(err)
}
for x, _ := range Product.Name {
fmt.Println(Product.Name[x], Product.Locs[x])
}
}
但这不会打印任何东西。我做错了什么?
以下是正在播放的完整代码https://play.golang.org/p/pZ6j4-lSEz。
答案 0 :(得分:3)
请尝试以下适用于我的代码(注意:您也可以像以前一样使用ioutil.ReadAll
和xml.Unmarshal
,而不是xml.Decode
):
package main
import (
"encoding/xml"
"fmt"
"log"
"net/http"
)
// <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">
// <url>
// <loc>
// https://www.notre-shop.com/products/test-product-releasing-soon-2
// </loc>
// <lastmod>2017-01-17T08:04:44Z</lastmod>
// <changefreq>daily</changefreq>
// <image:image>
// <image:loc>
// https://cdn.shopify.com/s/files/1/0624/0605/products/NOTRE-CHICAGO-QK9C9548_fde37b05-495e-47b0-8dd1-b053c9ed3545.jpg?v=1481853712
// </image:loc>
// <image:title>Test Product Releasing Soon 2</image:title>
// </image:image>
// </url>
// </urlset>
type URLSet struct {
XMLName string `xml:"urlset"`
URLs []URL `xml:"url"`
}
type URL struct {
Loc string `xml:"loc"`
Image Image `xml:"image"`
}
type Image struct {
Title string `xml:"title"`
}
func main() {
resp, err := http.Get("https://www.notre-shop.com/sitemap_products_1.xml")
if err != nil {
log.Fatalln(err) // log.Fatal always exits the program, need to check err != nil first
}
defer resp.Body.Close()
var urlSet URLSet
if err = xml.NewDecoder(resp.Body).Decode(&urlSet); err != nil {
log.Fatalln(err)
}
for _, url := range urlSet.URLs {
fmt.Println(url.Loc, url.Image.Title)
}
}
答案 1 :(得分:0)
这就是XML规范所说的
The Namespaces in XML Recommendation [XML Names] assigns a meaning to names containing colon characters. Therefore, authors should not use the colon in XML names except for namespace purposes, but XML processors must accept the colon as a name character.
这是XML命名空间建议书
XML命名空间建议书表达了一个通用名称 与XML 1.0兼容的间接方式。实际上是XML 命名空间建议书定义了从XML 1.0树到其中的映射 元素类型名称和属性名称是树中的本地名称 其中元素类型名称和属性名称可以是通用名称。 映射基于前缀的概念。如果是元素类型名称 或属性名称包含冒号,然后映射处理该部分 冒号前面的名称作为前缀,以及名称的一部分 冒号后作为本地名称。前缀foo是指URI 在xmlns:foo属性的值中指定。
你可能不会使用带冒号(:)的名称来获取内部元素而不是你可以避免修复,这里是你的代码重写
对于性能/内存注意事项,因为您获得io.Reader
,可以使用xml.Decoder
而不是xml.Unmarshal。
package main
import (
"encoding/xml"
"fmt"
"log"
"net/http"
)
var Product struct {
Locs []string `xml:"url>loc"`
Name []Image `xml:"url>image"`
}
type Image struct {
Title string `xml:"title"`
}
func main() {
res, err := http.Get("https://www.notre-shop.com/sitemap_products_1.xml")
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
decoder := xml.NewDecoder(res.Body)
err = decoder.Decode(&Product)
if err != nil {
log.Fatal(err)
}
for x, _ := range Product.Name {
fmt.Println(Product.Name[x].Title, Product.Locs[x])
}
}
这是播放链接play