解析动态XML
我知道如何将简单的xml数据解组为Go结构,但不知道如何处理动态标记。这里有一个例子。可以有解析动态XML,xml,parsing,go,struct,Xml,Parsing,Go,Struct,我知道如何将简单的xml数据解组为Go结构,但不知道如何处理动态标记。这里有一个例子。可以有等 <?xml version="1.0" encoding="utf-8"?> <products> <product> <product_id>11600</product_id> <date_created><![CDATA[2018-10-19 15:20:22]]></date_crea
等
<?xml version="1.0" encoding="utf-8"?>
<products>
<product>
<product_id>11600</product_id>
<date_created><![CDATA[2018-10-19 15:20:22]]></date_created>
<price>200</price>
<stock_status>In Stock</stock_status>
<images>
<image_1>1.jpg</image_1>
<image_2>2.jpg</image_2>
</images
</product>
</products>
当我运行fmt.Println(len(products.Product[0].Images))
时,我得到0。我缺少什么?您可以使用此库():
var输入=[]字节(`
你好
一
一
`)
类型产品结构{
XMLName xml.Name`xml:“产品”`
产品[]产品`xml:“产品”`
}
类型产品结构{
XMLName xml.Name`xml:“产品”`
名称字符串`xml:“名称”`
图像映射[字符串]接口{}
}
func(p*Product)解组xml(d*xml.Decoder,start xml.StartElement)错误{
var v结构{
XMLName xml.Name`xml:“产品”`
名称字符串`xml:“名称”`
图像结构{
内部[]字节`xml:,内部xml“`
}`xml:“图像”`
}
错误:=d.DecodeElement(&v,&start)
如果错误!=零{
返回错误
}
图像:=make(映射[字符串]接口{})
//在此处使用mxj并从v.images.Inner填充图像
p、 姓名
p、 图像=图像
归零
}
func main(){
var数据产品
错误:=xml.Unmarshal(输入和数据)
如果错误!=零{
恐慌(错误)
}
}
您可以在自定义映射类型上实现xml.Unmarshaler接口,如下所示:
type Images map[string]string
func (i *Images) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
*i = make(Images) // initialize the map
for {
tok, err := d.Token()
if err != nil {
if err == io.EOF {
return nil
}
return err
}
if se, ok := tok.(xml.StartElement); ok {
tok, err = d.Token()
if err != nil {
if err == io.EOF {
return nil
}
return err
}
if data, ok := tok.(xml.CharData); ok {
(*i)[se.Name.Local] = string(data)
}
}
}
}
您可以在自定义映射类型上实现xml.Unmarshaler接口,如下所示:此xml在您的控制下吗?因为动态标记是一种非常糟糕的做法party@mkopriva你的建议很有魅力。请将其添加为答案,以便我可以接受
var input = []byte(`<?xml version="1.0" encoding="utf-8"?>
<products>
<product>
<name>hello</name>
<images>
<image1>one</image1>
<image2>one</image2>
</images>
</product>
</products>`)
type Products struct {
XMLName xml.Name `xml:"products"`
Products []Product `xml:"product"`
}
type Product struct {
XMLName xml.Name `xml:"product"`
Name string `xml:"name"`
Images map[string]interface{}
}
func (p *Product) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var v struct {
XMLName xml.Name `xml:"product"`
Name string `xml:"name"`
Images struct {
Inner []byte `xml:",innerxml"`
} `xml:"images"`
}
err := d.DecodeElement(&v, &start)
if err != nil {
return err
}
images := make(map[string]interface{})
// use mxj here and fill images from v.Images.Inner
p.Name = v.Name
p.Images = images
return nil
}
func main() {
var data Products
err := xml.Unmarshal(input, &data)
if err != nil {
panic(err)
}
}
type Images map[string]string
func (i *Images) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
*i = make(Images) // initialize the map
for {
tok, err := d.Token()
if err != nil {
if err == io.EOF {
return nil
}
return err
}
if se, ok := tok.(xml.StartElement); ok {
tok, err = d.Token()
if err != nil {
if err == io.EOF {
return nil
}
return err
}
if data, ok := tok.(xml.CharData); ok {
(*i)[se.Name.Local] = string(data)
}
}
}
}