У меня есть эта игровая площадка: https://go.dev/play/p/uEpYEWaQaV0 Но так и не понял в чем проблема и почему не работает! и я получаю сообщение об ошибке:
invalid character entity &ccb
Мой код:
package main
import (
"encoding/xml"
"fmt"
)
type catalog struct {
Id string `xml:"id"`
}
type price struct {
Subtotal int `xml:"subtotal"`
Currency string `xml:"currency"`
Total int `xml:"total"`
PriceStatus string `xml:"price_status"`
}
type image struct {
Url string `xml:"url"`
Id int `xml:"id"`
}
type product struct {
Id int `xml:"id"`
RetailerId int `xml:"retailer_id"`
Image image `xml:"image"`
Price int `xml:"price"`
Currency string `xml:"currency"`
Name string `xml:"name"`
Quantity int `xml:"quantity"`
}
type order struct {
Product product `xml:"product"`
Catalog catalog `xml:"catalog"`
Price price `xml:"price"`
}
type Iq struct {
XMLName xml.Name `xml:"iq"`
Order order `xml:"order"`
}
func main() {
contents := `<iq from = "s.whatsapp.net" id = "162.120-3" type = "result">
<order creation_ts = "1651703902" id = "1046755402590219">
<product>
<id>8312993582051445</id>
<retailer_id>291</retailer_id>
<image>
<url>https://mmg.whatsapp.net/v/t45.5328-4/279646282_7510595942346471_4295336878174066544_n.jpg?stp=dst-jpg_p100x100&ccb=1-5&_nc_sid=c48759&_nc_ohc=OMyHhkGxzRoAX8Dn93Q&_nc_ad=z-m&_nc_cid=0&_nc_ht=mmg.whatsapp.net&oh=01_AVw_0loIIuK1LP-n5OL1hdpRmNYhAiUjLGk20FCclgNXCA&oe=62774C93</url>
<id>7510595939013138</id>
</image>
<price>5000</price>
<currency>SAR</currency>
<name>coffee</name>
<quantity>1</quantity>
</product>
<catalog><id>326185462964376</id></catalog>
<price>
<subtotal>5000</subtotal>
<currency>SAR</currency>
<total>5000</total>
<price_status>provided</price_status>
</price>
</order>
</iq>`
iq := &Iq{}
err := xml.Unmarshal([]byte(contents), &iq)
if err != nil {
panic(err)
}
fmt.Printf("%v\n", iq.Order)
}
XML в вашем коде имеет неправильный формат.
Фрагмент xml содержит элемент url
, который содержит URL-адрес с несколькими параметрами в части строки запроса, разделенных амперсандом &
.
Этот символ имеет специальную семантику в xml при инициировании ссылки на объект (своего рода символическая константа) — вы не можете использовать его изолированно.
Либо напишите URL-адрес в виде раздела CDATA (содержимое которого считается литералом, синтаксис: <![CDATA[
...]]>
), либо замените все вхождения &
на &
(используя ссылку на объект для спорта и символа; эффективно используется здесь как спасательный механизм).
Опираясь на ответ от @collapsar...
Несмотря на искаженный формат XML, вы все равно можете обработать его, создав экземпляр Decoder
и отключив режим Strict
:
d := xml.NewDecoder(bytes.NewReader([]byte(contents)))
d.Strict = false
err := d.Decode(&iq)
if err != nil {
panic(err)
}
fmt.Printf("%v\n", iq.Order)
Для справки см. https://pkg.go.dev/encoding/xml#Декодер.
Спасибо, первый вариант у меня не сработал: go.dev/play/p/PUYabxnaUZX, зато отлично сработал второй: go.dev/play/p/sqQJQog98Ug