1

I'm trying to parse the following XML by attribute and value.

<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>

I've come up with the following

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"`
}

which produces

  "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"
        }
      ]
    },

The desired output would be

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

I've been trying to achieve this for hours and I haven't found a way yet.

1 Answer 1

3

You can unmarshal inner XML into a map by using a custom UnmarshalXML method:

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
}

Playground: https://play.golang.org/p/87v_vTXpB-.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your reponse! This really helped! I can't make it work with opening a file containing the XML though. play.golang.org/p/G8n8Ql6DVx is what I tried. The test.xml file contains the xml with multiple dox tags.
@leandermelms You may need to ask a new question and provide a better example of your XML document and what you want as a result.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.