Golang, синтаксический анализ xml в struct?

#go #xml-parsing

#Вперед #xml-синтаксический анализ

Вопрос:

У меня есть такой XML-документ, и мне нужно получить массив ДАННЫХ. Я не могу решить эту простую задачу в течение 4 часов…. хотите вернуться к node.js 🙂

 <?xml version="1.0" standalone="no"?>
<RETS ReplyCode="0" ReplyText="Operation Successful" >
<COUNT Records="58951" />
<DELIMITER value="09"/>
<COLUMNS>   LN  </COLUMNS>
<DATA>  09361303    </DATA>
<DATA>  09333085    </DATA>
<MAXROWS/>
  

 type DATA struct {
    DATA string `xml:"DATA"`
}

type Rets struct {
    DATA []DATA `xml:"RETS>DATA"`
}


data := amp;Rets{}
decoder := xml.Unmarshal(body,amp;data)

fmt.Println(decoder)
  

Комментарии:

1. decoder возвращается ли ошибка xml.Unmarshal , и вы передаете a **Rets Unmarshal , а не a *Rets .

2. извините, конечно, fmt. Println(данные), но я получил пустой объект

3. Тем не менее, количество элементов правильное, но они пустые.

4. rdata := new(Rets) err = xml.Unmarshal(body, amp;rdata) fmt. Println(rdata) amp;{[{} {} {} {} {}] Однако количество элементов массива правильное — может быть, это из-за пробелов в элементах ДАННЫХ?

Ответ №1:

Есть несколько инструментов для превращения XML в структуры Go. Один из них, который подходит для чтения, — это zek (попробуйте его онлайн), и хотя он экспериментальный, он уже может работать с несколькими распространенными XML-конструкциями.

Вы можете перейти от XML-файла (raw) к struct с помощью простой команды:

 $ curl -sL https://git.io/fN4Pq | zek -e -p -c
  

Это создаст struct плюс пример программы для тестирования маршалинга (пример делает очень мало, он считывает XML из stdin и превращает его в JSON).

Вот пример struct (для некоторого XML, взятого из этого репозитория):

 // RETS was generated 2018-09-07 12:11:10 by tir on apollo.local.
type RETS struct {
    XMLName       xml.Name `xml:"RETS"`
    Text          string   `xml:",chardata"`
    ReplyCode     string   `xml:"ReplyCode,attr"`
    ReplyText     string   `xml:"ReplyText,attr"`
    METADATATABLE struct {
        Text     string   `xml:",chardata"`
        Resource string   `xml:"Resource,attr"`
        Class    string   `xml:"Class,attr"`
        Version  string   `xml:"Version,attr"`
        Date     string   `xml:"Date,attr"`
        COLUMNS  string   `xml:"COLUMNS"` // MetadataEntryID    SystemNam...
        DATA     []string `xml:"DATA"`    // 7  City        City    Ci ...
    } `xml:"METADATA-TABLE"`
}
  

Отказ от ответственности: я написал zek.

Ответ №2:

Из xml.Unmarshal документов

  • Если элемент XML содержит символьные данные, эти данные накапливаются в первом поле struct, которое имеет тег «,chardata». Поле struct может иметь тип []байт или строка. Если такого поля нет, символьные данные отбрасываются.

Использовать

 type DATA struct {
    DATA string `xml:",chardata"`
}

type Rets struct {
    DATA []DATA `xml:"DATA"`
}
  

Или в этом простом случае вы можете просто использовать

 type Rets struct {
    DATA []string `xml:"DATA"`
}
  

Который по умолчанию собирает charadata из списка элементов

Комментарии:

1. Вау, Джим. СПАСИБО ВАМ ОООЧЕНЬ БОЛЬШОЕ! Я думал, что моя попытка переключиться на go не удалась на шаге 1 :-)!

2. Отлично, оба работают. Я не совсем понимаю, откуда взялись chardata, но я буду читать документы больше :-). Хорошего дня!