Использование для преобразования больших файлов XML в JSON для хранения в MongoDB - PullRequest
0 голосов
/ 08 октября 2018

Для моего проекта мне приходится иметь дело с файлами XML размером более 2 ГБ.Я хотел бы хранить данные mongoDB.Я решил попробовать его на языке Go.Но у меня возникли проблемы с поиском лучшего способа сделать это в Go.

Я видел много примеров с фиксированной структурой XML, но структура данных, которую я получаю, является динамической, поэтому я использую некоторыевид предопределенной структуры не будет работать для меня.

Теперь я наткнулся на этот пакет: https://github.com/basgys/goxml2json, который выглядит очень многообещающе, но есть несколько вещей, которые я не понимаю:

  • В примере, приведенном в файле readme, используется строка XML, но я не вижу ничего в коде, который принимает файл.
  • Учитывая пример, у меня есть 2 ГБ XML-файлыЯ не могу просто загрузить весь XML-файл в память.Это затопит мой сервер.

Я думаю, что хорошо бы сказать, мне просто нужно преобразовать данные XML один раз в их форму JSON, чтобы я мог сохранить их в mongoDB.

Есть ли у кого-нибудь идеи о том, как эффективно анализировать XML-файлы в JSON с помощью Go?

1 Ответ

0 голосов
/ 09 октября 2018

Go предоставляет встроенный синтаксический анализатор потока XML со значением encoding/xml.Decoder.

. Типичным примером использования является чтение токенов до тех пор, пока вы не найдете что-то интересное, а затем демонтирование токена в тег XML.struct, а затем обрабатывать эти данные соответственно.Таким образом, вы загружаете в память только то, что требуется для одного XML-токена или , чтобы демонтировать интересующий бит данных.

Например ( Go Playground ):

d := xml.NewDecoder(xmlStream)
for {
  // Decode the next token from the stream...
  token, err := d.Token()
  if err == io.EOF {
    break
  }
  check(err)

  // Switch behavior based on the token type.
  switch el := token.(type) {
  case xml.StartElement:
    // Handle "person" start elements by unmarshaling from XML...
    if el.Name.Local == "person" {
      var p Person
      err := d.DecodeElement(&p, &el)
      check(err)

      // ...then marshal to JSON...
      jsonbytes, err := json.Marshal(p)
      check(err)

      // ...then take other action (e.g. insert into database).
      fmt.Printf("OK: %s\n", string(jsonbytes))
      // OK: {"Id":"123","Name":"Alice","Age":30}
    }
  }
}
...