Unmarshal XML в карту

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

Если бы кто-нибудь мог дать какие-либо рекомендации по этому поводу, это было бы весьма признательно.

XML: Повторяются функции classAccesses, и есть несколько других элементов.

<classaccesses>
 <apexclass>AccountRelationUtility</apexclass>
 <enabled>true</enabled>
</classaccesses>

Моя текущая структура: сначала анализирую каждый элемент заголовка, а затем создаю новую структуру с дочерними элементами

type classAccesses struct {
 ApexClass string 'xml:"apexClass"'
 Enabled string 'xml:"enabled"'
}

type diffs struct {
 ClassAccesses []classAccesses 'xml:"classAccesses"'
}

Желаемая карта: я хочу сохранить diffs struct, но я хочу, чтобы дочерняя структура ClassAccesses стала похожей на приведенную ниже карту.

map[string]string {
 "ApexClass": "enabled"
}
2 ответа

Начиная с Go 1.3, невозможно развязать XML-документ непосредственно на карте, используя стандартную библиотеку Go.

XML-часть стандартной библиотеки приведена здесь, http://golang.org/pkg/encoding/xml/, нет функций, которые могли бы выполнять именно то, что вы просите в вопросе.

В зависимости от специфики вашей ситуации у вас могут быть другие варианты, такие как:

  • Параллелизируйте свой алгоритм, то есть читайте из файла и декодируйте в одно и то же время. Это будет работать только при наличии нескольких файлов для чтения.
  • Напишите свой собственный алгоритм декодирования XML в Go.


Если вы создаете тип, реализующий интерфейс xml.Unmarshaller, вы можете упорядочить ваши данные непосредственно в строку [string].

type classAccessesMap struct {
 m map[string]string
}

func (c *classAccessesMap) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
 c.m = map[string]string{}

 key := ""
 val := ""

 for {
 t, _ := d.Token()
 switch tt := t.(type) {

 // TODO: parse the inner structure

 case xml.StartElement:
 fmt.Println(">", tt) 

 case xml.EndElement:
 fmt.Println("<", tt)
 if tt.Name == start.Name {
 return nil
 }

 if tt.Name.Local == "enabled" {
 c.m[key] = val
 }
 }
 }
}

Вот частичное решение; https://play.golang.org/p/7aOQ5mcH6zQ

licensed under cc by-sa 3.0 with attribution.