dph58509 2018-09-05 20:31
浏览 50
已采纳

将XML解析为包含切片的结构

Situation:

I have this XML structure:

<group id="26659127">
    <member ref="292403538"/>
    <member ref="298884289"/>
    <member ref="261728686"/>
    <info k="name" v="omega"/>
    <info k="rank" v="16"/>
</group>

I need to convert this XML into this struct:

{
    Id: "26659127",
    Members: ["26659127", "298884289", "261728686"],
    Info: [
        {
            Key: "name",
            Value: "omega"
        },
        {
            Key: "rank",
            Value: "16"
        }
    ]
}

Problem:

I created a struct for parsing XML already:

type Group struct {
    Id      string   `xml:"id,attr"`
    Members []string `xml:" "`
    Info    []Info   `xml:"info"`
}

type Info struct {
    Key     string   `xml:"k,attr"`
    Value   string   `xml:"v,attr"`
}

But, as you can see I haven't defined an expression for Members yet. Actually, I tried putting xml:"member,ref,attr" and xml:"member:ref,attr" in here, but it didn't work.

Question:

Is there a possibility to solve this issue? If yes, what expression I should use?

  • 写回答

1条回答 默认 最新

  • dtrnish3637 2018-09-06 14:42
    关注

    Unfortunately there is no way to use the default XML unmarshaler to achieve your goal by using only struct field tags so you'll have to either:

    1. Extract a struct type for the "Members" field which has a "ref" field (similar to the "Info" type).
    2. Use a custom type for "Member" which is a string and implements xml.Unmarshaler by extracting the value of the "ref" attribute from the associated XML element.

    Here is an example of how you can implement strategy #2 above (Go Playground):

    type Group struct {
      Id      string      `xml:"id,attr"`
      Members []MemberRef `xml:"member"`
      Info    []Info      `xml:"info"`
    }
    
    type MemberRef string
    
    func (m *MemberRef) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
      *m = MemberRef(start.Attr[0].Value) // Assume only the "ref" attribute exists.
      _, err := d.Token() // Consume and discard the synthetic xml.EndElement.
      return err
    }
    
    // ...
    var group Group
    err := xml.Unmarshal([]byte(xmlstr), &group)
    if err != nil {
        panic(err)
    }
    fmt.Printf("%#v
    ", group)
    // main.Group{Id:"26659127", Members:[]main.MemberRef{"292403538", "298884289", "261728686"}, Info:...
    

    Note that you can even marshal this struct directly into the example JSON format you listed:

    bs, err := json.MarshalIndent(group, "", "  ")
    if err != nil {
        panic(err)
    }
    fmt.Println(string(bs))
    // {
    //   "Id": "26659127",
    //   "Members": [
    //     "292403538",
    //     "298884289",
    //     "261728686"
    //   ],
    //   "Info": [
    //     ...
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 minnio内存占用过大,内存没被回收(Windows环境)
  • ¥65 抖音咸鱼付款链接转码支付宝
  • ¥15 ubuntu22.04上安装ursim-3.15.8.106339遇到的问题
  • ¥15 求螺旋焊缝的图像处理
  • ¥15 blast算法(相关搜索:数据库)
  • ¥15 请问有人会紧聚焦相关的matlab知识嘛?
  • ¥15 网络通信安全解决方案
  • ¥50 yalmip+Gurobi
  • ¥20 win10修改放大文本以及缩放与布局后蓝屏无法正常进入桌面
  • ¥15 itunes恢复数据最后一步发生错误