2

我正在通过编写一个以Collada格式生成文件的程序来学习 Go,该文件使用 XML 描述几何。

你注释你的结构,几乎所有的东西都像你期望的那样工作,除了我不知道如何将数组编组到一个 XML 元素中——我总是最终生成 N 个元素。

换句话说,我想

<input>
    <p>0 1 2</p>
</input> 

代替

<input>
    <p>0</p>
    <p>1</p>
    <p>2</p>
</input> 

代码如下

package main

import (
    "encoding/xml"
    "os"
)

func main() {
    type Vert struct {
        XMLName xml.Name    `xml:"input"`
        Indices     []int   `xml:"p"`
    }

    v := &Vert{Indices:[]int{0, 1, 2}}
    output, err := xml.MarshalIndent(v, "", "    ")
    if err == nil {
        os.Stdout.Write(output)
    }
}

encoding/xml/marshal.go中的各种注释(和代码)似乎暗示我不走运:

// Marshal 通过编组每个元素来处理数组或切片。
// 切片和数组遍历元素。它们没有封闭标签。

奇怪的是,如果我将数组类型更改为 uint8,则根本不会对数组进行编组。

如果我不走运,我可能会使用 xml:",innerxml" 注释自己替换数组。

4

2 回答 2

1

正如您所猜测的,encoding/xml 将无法立即执行此操作。你可以这样做:

import (
    "strconv"
    "strings"
)

type Vert struct {
    P string `xml:"p"`
}

func (v *Vert) SetIndices(indices []int) {
    s := make([]string, len(indices))
    for i := range indices {
        s[i] = strconv.FormatInt(int64(indices[i]), 10)
    }
    v.P = strings.Join(s, " ")
}

编辑:我最初写了一个 getter 而不是 setter。

于 2012-12-10T06:13:18.940 回答
0

最后,我通过将类型更改为string并使用innerxml属性,对这种类型的数组进行了自己的 xml 编组。

package main

import (
    "encoding/xml"
    "os"
    "fmt"
    "bytes"
)

func MyMarshalArray(indices []int) string {
    var buffer bytes.Buffer

    buffer.WriteString("<p>")
    for i := 0; i < len(indices); i++ {
        buffer.WriteString(fmt.Sprintf("%v ", indices[i]))
    }
    buffer.WriteString("</p>")
    return buffer.String()
}

func main() {
    type Vert struct {
        XMLName xml.Name    `xml:"input"`
        Indices     string  `xml:",innerxml"`
    }

    v := &Vert{Indices:MyMarshalArray([]int{0, 1, 2})}
    output, err := xml.MarshalIndent(v, "", "    ")
    if err == nil {
        os.Stdout.Write(output)
    }
}
于 2012-12-12T05:02:39.377 回答