通过标记属性将XML解析为struct

时间:2017-03-10 14:53:27

标签: xml go

我试图按属性和值解析以下XML。

<result name="response" numFound="10775" start="0" maxScore="0.59509283">
    <doc>
        <str name="cui">c0162311</str>
        <str name="display_title">Androgenetic alopecia</str>
        <str name="source">GHR</str>
        <str name="source_url">http://ghr.nlm.nih.gov/condition/androgenetic-alopecia</str>
        <float name="score">0.59509283</float>
    </doc>

我已经提出以下

type Response struct {
    StrDoc []Str `xml:"result>doc"`
}

type Str struct {
    Doc   []Doc   `xml:"str"`
    Score []Score `xml:"float"`
}

type Doc struct {
    Key   string `xml:"name,attr"`
    Value string `xml:",chardata"`
}

type Score struct {
    Score string `xml:",chardata"`
}

产生

  "StrDoc": [
    {
      "Doc": [
        {
          "Key": "cui",
          "Value": "c0162311"
        },
        {
          "Key": "display_title",
          "Value": "Androgenetic alopecia"
        },
        {
          "Key": "source",
          "Value": "GHR"
        },
        {
          "Key": "source_url",
          "Value": "http://ghr.nlm.nih.gov/condition/androgenetic-alopecia"
        }
      ],
      "Score": [
        {
          "Score": "0.59509283"
        }
      ]
    },

所需的输出是

"Doc": [
            {
              "cui": "c0162311",
              "display_title": "Androgenetic alopecia",
              "source": "GHR",
              "Value": "GHR",
              "source_url": "http://ghr.nlm.nih.gov/",
              "Score": "0.59509283"
            }
          ]

我一直在努力实现这个目标几个小时,但我还没有找到办法。

1 个答案:

答案 0 :(得分:1)

您可以使用自定义UnmarshalXML方法将内部XML解组为地图:

type Result struct {
    Doc Doc `xml:"doc"`
}

type Doc struct {
    Elems map[string]string
}

func (doc *Doc) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) {
    type entry struct {
        Key   string `xml:"name,attr"`
        Value string `xml:",chardata"`
    }
    e := entry{}
    doc.Elems = map[string]string{}
    for err = d.Decode(&e); err == nil; err = d.Decode(&e) {
        doc.Elems[e.Key] = e.Value
    }
    if err != nil && err != io.EOF {
        return err
    }
    return nil
}

游乐场:https://play.golang.org/p/87v_vTXpB-