我正在学习Go,编写一个以Collada格式生成文件的程序,该程序使用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”注释自己替换数组。
答案 0 :(得分: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。
答案 1 :(得分:0)
最后我为这种类型的数组做了我自己的xml编组,
将类型更改为string
并使用innerxml
属性。
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)
}
}