Golang unmarshal将结构索引更改为定义值

时间:2017-09-11 12:37:11

标签: xml go unmarshalling

见下面的代码:

打印出v.Src [0],v.Src [1]显示“MySource”和“MySource2”。

但是比较XML,条目[0]和[1]不遵循<id>x</id>中的id设置

如何实现解码器使用<id>x</id>作为索引?

目标:v.Src [1]打印“MySource”

这是我的工作代码

package main

import (

    "encoding/xml"
    "fmt"
)

    type Flow struct {
        Id   string `xml:"id"`
        Name string `xml:"name"`
    }
    type Src struct {
        Id    string `xml:"id"`
        Name  string `xml:"name"`
        Flows []Flow `xml:"flows>flow"`
    }
    type Result struct {
        Src   []Src  `xml:"bar>sources>source"`


    }

func main() {
    data := `
    <foo>
        <bar>
            <sources>
                <source>
                  <id>1</id>
                    <name>MySource</name>

                    <flows>
                      <flow>
                        <id>1</id>
                        <name>MySource 1L</name>
                      </flow>
                      <flow>
                        <id>2</id>
                        <name>MySource 1R</name>
                      </flow>
                    </flows>   
                </source>
                <source>
                  <id>2</id>
                    <name>MySource2</name>

                    <flows>
                      <flow>
                        <id>1</id>
                        <name>MySource2 2L</name>
                      </flow>
                      <flow>
                        <id>2</id>
                        <name>MySource2 2R</name>
                      </flow>
                    </flows>   
                </source>
            </sources>
        </bar>
    </foo>`

    v := Result{}

    err := xml.Unmarshal([]byte(data), &v)
    if err != nil {
        fmt.Printf("error: %v", err)
        return
    }
    fmt.Printf("%#v", v)
    fmt.Printf("%#v", v.Src[0].Name) //Prints: "MySource"
    fmt.Printf("%#v", v.Src[1].Name) //Prints: "MySource2"
}

非常感谢所有人的帮助!

1 个答案:

答案 0 :(得分:0)

由于v.Src是一个带Src的切片,其索引仅显示元素的顺序,但不显示其内部字段。如何解决任务:

  1. 使用指向元素的指针制作特殊地图

    srcs := make(map[int64]*Src)
    
    for index, src := range v.Src {
        id, _ := strconv.ParseInt(src.Id, 10, 64)
        srcs[id] = &(v.Src[index])
    }
    
    fmt.Printf("Srcs: %v\n", srcs)
    fmt.Printf("%#v\n", srcs[1].Name) //Prints: "MySource"
    fmt.Printf("%#v\n", srcs[2].Name) //Prints: "MySource2"
    

    https://play.golang.org/p/6y3uW2jV13

  2. 使用XPath访问具有特定属性的元素,然后选择//source[./id=1]/name