пятница, 26 июня 2020 г.

Пакет xml в Golang - метод Unmarshal

func Unmarshal(data []byte, v interface{}) error

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

Поскольку Unmarshal использует пакет reflect, он может назначать только экспортированные поля (в верхнем регистре). Unmarshal использует сравнение с учетом регистра для сопоставления имен элементов XML с тегами значений и структурных имен полей.

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

  • Если структура имеет поле типа []byte или string с тегом ",innerxml", Unmarshal накапливает сырой XML, вложенный в элемент в этой области. Остальные правила все еще применяются.
  • Если в структуре есть поле с именем XMLName типа Name, Unmarshal записывает имя элемента в этом поле.
  • Если у поля XMLName есть связанный тег формы "name" или "namespace-URL name", элемент XML должен иметь имя (и, возможно, пространство имен) или Unmarshal возвращает ошибку.
  • Если элемент XML имеет атрибут, имя которого соответствует имени структурного поля со связанным тегом, содержащим ",attr" или явное имя в теге структурного поля вида "name,attr", Unmarshal записывает значение атрибута в это поле.
  • Если элемент XML имеет атрибут, не обработанный предыдущим правилом и структура имеет поле со связанным тегом, содержащим ",any,attr", Unmarshal записывает значение атрибута в первое такое поле.
  • Если элемент XML содержит символьные данные, эти данные накапливается в первом структурном поле с тегом "chardata". Поле структуры может иметь тип []byte или string. Если такого поля нет, символьные данные отбрасываются.
  • Если элемент XML содержит комментарии, они накапливаются в первое поле структуры, которое имеет тег ",comment". Структурное поле может иметь тип []byte или string. Если нет такого поля, комментарии отбрасываются.
  • Если элемент XML содержит подэлемент, имя которого совпадает префикс тега, отформатированный как "a" или "a>b>c", unmarshal опустится в структуру XML в поисках элементов с заданными именами, и сопоставит самые внутренние элементы с этой структурой поле. Тег, начинающийся с ">", эквивалентен одному стартовому с именем поля, сопровождаемым ">".
  • Если элемент XML содержит подэлемент, имя которого совпадает с тегом XMLName поля структуры, а поле структуры не имеет явный тег name в соответствии с предыдущим правилом, демаршал картирует подэлемент в этом поле структуры.
  • Если элемент XML содержит подэлемент, имя которого соответствует поле без каких-либо флагов режима (",attr", ",chardata" и т. д.), Unmarshal сопоставляет подэлемент с этим структурным полем.
  • Если элемент XML содержит подэлемент, который не соответствует ни одному из вышеперечисленных правил и структура имеет поле с тегом ",any", unmarshal отображает вложенный элемент в это структурное поле.
  • Анонимное поле структуры обрабатывается так, как если бы поля его значения были частью внешней структуры.
  • Поле структуры с тэгом "-" никогда не записывается.

Если Unmarshal встречает тип поля, который реализует интерфейс Unmarshaler, Unmarshal вызывает свой метод UnmarshalXML для получения значения из элемента XML. В противном случае, если значение реализует encoding.TextUnmarshaler, Unmarshal вызывает метод UnmarshalText этого значения.

Unmarshal отображает элемент XML в string или []byte, сохраняя объединение символьных данных этого элемента в string или []byte. Сохраненный []byte никогда не равен nil.

Unmarshal отображает значение атрибута в string или []byte, сохраняя значение в строке или срезе.

Unmarshal отображает значение атрибута в Attr, сохраняя атрибут, включая его имя, в Attr.

Unmarshal отображает элемент XML или значение атрибута на срез, увеличивая длину среза и сопоставляя элемент или атрибут с вновь созданным значением.

Unmarshal отображает значение элемента XML или атрибута в логическое значение, устанавливая для него логическое значение, представленное строкой. Пустое пространство обрезается и игнорируется.

Unmarshal отображает элемент XML или значение атрибута в целочисленное поле или поле с плавающей запятой, устанавливая в поле результат интерпретации строкового значения в десятичном виде. Нет проверки на переполнение. Пустое пространство обрезается и игнорируется.

Unmarshal отображает элемент XML на имя путем записи имени элемента.

Unmarshal отображает элемент XML на указатель, устанавливая указатель на только что выделенное значение, а затем сопоставляя элемент с этим значением.

Отсутствующий элемент или пустое значение атрибута будет отменено как нулевое значение. Если поле является срезом, к нему будет добавлено нулевое значение. В противном случае поле будет установлено в его нулевое значение.

Пример использования Unmarshal

Этот пример демонстрирует демаршализацию выдержки XML в значение с некоторыми предустановленными полями. Обратите внимание, что поле Phone не изменено, а элемент XML <Company> игнорируется. Кроме того, поле Groups назначается с учетом пути элемента, указанного в его теге.

package main

import (
    "encoding/xml"
    "fmt"
)

func main() {
    type Email struct {
        Where string `xml:"where,attr"`
        Addr  string
    }
    type Address struct {
        City, State string
    }
    type Result struct {
        XMLName xml.Name `xml:"Person"`
        Name    string   `xml:"FullName"`
        Phone   string
        Email   []Email
        Groups  []string `xml:"Group>Value"`
        Address
    }
    v := Result{Name: "none", Phone: "none"}

    data := `
        <Person>
            <FullName>Grace R. Emlin</FullName>
            <Company>Example Inc.</Company>
            <Email where="home">
                <Addr>gre@example.com</Addr>
            </Email>
            <Email where='work'>
                <Addr>gre@work.com</Addr>
            </Email>
            <Group>
                <Value>Friends</Value>
                <Value>Squash</Value>
            </Group>
            <City>Hanga Roa</City>
            <State>Easter Island</State>
        </Person>
    `
    err := xml.Unmarshal([]byte(data), &v)
    if err != nil {
        fmt.Printf("error: %v", err)
        return
    }
    fmt.Printf("XMLName: %#v\n", v.XMLName)
    fmt.Printf("Name: %q\n", v.Name)
    fmt.Printf("Phone: %q\n", v.Phone)
    fmt.Printf("Email: %v\n", v.Email)
    fmt.Printf("Groups: %v\n", v.Groups)
    fmt.Printf("Address: %v\n", v.Address)
}

Вывод:

XMLName: xml.Name{Space:"", Local:"Person"}
Name: "Grace R. Emlin"
Phone: "none"
Email: [{home gre@example.com} {work gre@work.com}]
Groups: [Friends Squash]
Address: {Hanga Roa Easter Island}


Читайте также:


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

Отправить комментарий