Проблемы с кодировкой Go XML - PullRequest
0 голосов
/ 28 декабря 2018

Мне нужно создать следующий xml:

<AccessControlList>
    <Grant>
        <Grantee
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
            <ID>xxxx-xx</ID>
            <DisplayName>rahul.khan</DisplayName>
        </Grantee>
        <Permission>FULL_CONTROL</Permission>
    </Grant>
</AccessControlList>

Моя структура определяется следующим образом:

type Grantee struct {
Xmlns_xsi   string `xml:"xmlns xsi,attr,omitempty"`
Xsi_type    string `xml:"http://www.w3.org/2001/XMLSchema-instance type,attr,omitempty"`
ID          string `xml:",omitempty"`
DisplayName string `xml:",omitempty"`

}

Однако, когда я собираю эту структуру,Получаемый XML-документ выглядит следующим образом:

<AccessControlList>
    <Grant>
        <Grantee
            xmlns:XMLSchema-instance="http://www.w3.org/2001/XMLSchema-instance" XMLSchema-instance:type="CanonicalUser">
            <ID>xxxx-xx</ID>
            <DisplayName>rahul.khan</DisplayName>
        </Grantee>
        <Permission>FULL_CONTROL</Permission>
    </Grant>
</AccessControlList>

В результате, когда документ не распакован, поле типа, по-видимому, не анализируется aws-go-sdk.

Например, это необработанный вывод, который мне нужно получить

Grantee: {
    DisplayName: "rahul.khan",
    ID: "xxxx-xx",
    Type: "CanonicalUser"
  },
  Permission: "FULL_CONTROL"
}

Вместо этого я получаю следующее:

  Grantee: {
    DisplayName: "rahul.khan",
    ID: "xxxx-xx"
  },
  Permission: "FULL_CONTROL"
}

Кажется, что атрибут Type отсутствуетиз некоммерческого выхода.Единственное отличие, которое я вижу в xml-документе, созданном моим кодом и в aws, состоит в том, что эта строка

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser" v / s

xmlns:XMLSchema-instance="http://www.w3.org/2001/XMLSchema-instance" XMLSchema-instance:type="CanonicalUser"

Оцените, если кто-томожете помочь мне понять, как решить эту проблему?

1 Ответ

0 голосов
/ 28 декабря 2018

Эта структура Marshals для XML вам нужна, используя просто endcoding / xml.Marshal ():

type Grantee struct {
    Xmlns_xsi   string `xml:"xmlns:xsi,attr,omitempty"`  //set namespace prefix explicitly
    Xsi_type    string `xml:"xsi:type,attr,omitempty"`   //set namespace:attr  explicitly
    ID          string `xml:",omitempty"`
    DisplayName string `xml:",omitempty"`
}

g := Grantee{
    DisplayName: "rahul.khan",
    ID:          "xxxx-xx",
    Xsi_type:    "CanonicalUser",
    Xmlns_xsi:   "http://www.w3.org/2001/XMLSchema-instance", // set namespace URI as the value of the field
}

gm, err := xml.MarshalIndent(g, "", "  ")
if err != nil {
    fmt.Printf("error: %v", err)
    return
}

fmt.Printf("%+s\n", gm)

//<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
//  <ID>xxxx-xx</ID>
//  <DisplayName>rahul.khan</DisplayName>
//</Grantee>

https://play.golang.org/p/zrVlmktLyZu

Обратите внимание, что xmlns:xsi и xsi:typeпросто устанавливаются как явные имена атрибутов, включая двоеточия.Как вы обнаружили, если вы оставляете пробел между пространством имен и именем атрибута, encoding / xml вносит изменения в попытке очистить пространства имен в выходных данных (как, например, использование последней части URL-адреса пространства имен в качестве префикса пространства имен: например, XMLSchema-instance).

Я признаю, что этот XML может не распаковывать в вашей структуре Go так, как вам бы хотелось (как обсуждалось во многих проблемах golang, таких как тот, на который ссылается @Adrian в комментарии к вашему вопросу).Но, если вы отправляете S3 Rest API для изменения ACL, похоже, этот xml будет правильным).Похоже, что aws-go-sdk использует собственную функцию для десериализации XML, так что попробуйте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...