将XML解析为带有标签属性的结构体。

huangapple go评论108阅读模式
英文:

Go Parse XML to struct by tag attribute

问题

我正在尝试按属性和值解析以下XML。

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

我已经得到了以下结果

  1. type Response struct {
  2. StrDoc []Str `xml:"result>doc"`
  3. }
  4. type Str struct {
  5. Doc []Doc `xml:"str"`
  6. Score []Score `xml:"float"`
  7. }
  8. type Doc struct {
  9. Key string `xml:"name,attr"`
  10. Value string `xml:",chardata"`
  11. }
  12. type Score struct {
  13. Score string `xml:",chardata"`
  14. }

它产生了

  1. "StrDoc": [
  2. {
  3. "Doc": [
  4. {
  5. "Key": "cui",
  6. "Value": "c0162311"
  7. },
  8. {
  9. "Key": "display_title",
  10. "Value": "Androgenetic alopecia"
  11. },
  12. {
  13. "Key": "source",
  14. "Value": "GHR"
  15. },
  16. {
  17. "Key": "source_url",
  18. "Value": "http://ghr.nlm.nih.gov/condition/androgenetic-alopecia"
  19. }
  20. ],
  21. "Score": [
  22. {
  23. "Score": "0.59509283"
  24. }
  25. ]
  26. },

期望的输出应该是

  1. "Doc": [
  2. {
  3. "cui": "c0162311",
  4. "display_title": "Androgenetic alopecia",
  5. "source": "GHR",
  6. "Value": "GHR",
  7. "source_url": "http://ghr.nlm.nih.gov/",
  8. "Score": "0.59509283"
  9. }
  10. ]

我已经尝试了几个小时,但还没有找到解决方法。

英文:

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

  1. &lt;result name=&quot;response&quot; numFound=&quot;10775&quot; start=&quot;0&quot; maxScore=&quot;0.59509283&quot;&gt;
  2. &lt;doc&gt;
  3. &lt;str name=&quot;cui&quot;&gt;c0162311&lt;/str&gt;
  4. &lt;str name=&quot;display_title&quot;&gt;Androgenetic alopecia&lt;/str&gt;
  5. &lt;str name=&quot;source&quot;&gt;GHR&lt;/str&gt;
  6. &lt;str name=&quot;source_url&quot;&gt;http://ghr.nlm.nih.gov/condition/androgenetic-alopecia&lt;/str&gt;
  7. &lt;float name=&quot;score&quot;&gt;0.59509283&lt;/float&gt;
  8. &lt;/doc&gt;

I've come up with the following

  1. type Response struct {
  2. StrDoc []Str `xml:&quot;result&gt;doc&quot;`
  3. }
  4. type Str struct {
  5. Doc []Doc `xml:&quot;str&quot;`
  6. Score []Score `xml:&quot;float&quot;`
  7. }
  8. type Doc struct {
  9. Key string `xml:&quot;name,attr&quot;`
  10. Value string `xml:&quot;,chardata&quot;`
  11. }
  12. type Score struct {
  13. Score string `xml:&quot;,chardata&quot;`
  14. }

which produces

  1. &quot;StrDoc&quot;: [
  2. {
  3. &quot;Doc&quot;: [
  4. {
  5. &quot;Key&quot;: &quot;cui&quot;,
  6. &quot;Value&quot;: &quot;c0162311&quot;
  7. },
  8. {
  9. &quot;Key&quot;: &quot;display_title&quot;,
  10. &quot;Value&quot;: &quot;Androgenetic alopecia&quot;
  11. },
  12. {
  13. &quot;Key&quot;: &quot;source&quot;,
  14. &quot;Value&quot;: &quot;GHR&quot;
  15. },
  16. {
  17. &quot;Key&quot;: &quot;source_url&quot;,
  18. &quot;Value&quot;: &quot;http://ghr.nlm.nih.gov/condition/androgenetic-alopecia&quot;
  19. }
  20. ],
  21. &quot;Score&quot;: [
  22. {
  23. &quot;Score&quot;: &quot;0.59509283&quot;
  24. }
  25. ]
  26. },

The desired output would be

  1. &quot;Doc&quot;: [
  2. {
  3. &quot;cui&quot;: &quot;c0162311&quot;,
  4. &quot;display_title&quot;: &quot;Androgenetic alopecia&quot;,
  5. &quot;source&quot;: &quot;GHR&quot;,
  6. &quot;Value&quot;: &quot;GHR&quot;,
  7. &quot;source_url&quot;: &quot;http://ghr.nlm.nih.gov/&quot;,
  8. &quot;Score&quot;: &quot;0.59509283&quot;
  9. }
  10. ]

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

答案1

得分: 3

你可以通过使用自定义的UnmarshalXML方法,将内部XML解组为一个map:

  1. type Result struct {
  2. Doc Doc `xml:"doc"`
  3. }
  4. type Doc struct {
  5. Elems map[string]string
  6. }
  7. func (doc *Doc) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) {
  8. type entry struct {
  9. Key string `xml:"name,attr"`
  10. Value string `xml:",chardata"`
  11. }
  12. e := entry{}
  13. doc.Elems = map[string]string{}
  14. for err = d.Decode(&e); err == nil; err = d.Decode(&e) {
  15. doc.Elems[e.Key] = e.Value
  16. }
  17. if err != nil && err != io.EOF {
  18. return err
  19. }
  20. return nil
  21. }

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

英文:

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

  1. type Result struct {
  2. Doc Doc `xml:&quot;doc&quot;`
  3. }
  4. type Doc struct {
  5. Elems map[string]string
  6. }
  7. func (doc *Doc) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) {
  8. type entry struct {
  9. Key string `xml:&quot;name,attr&quot;`
  10. Value string `xml:&quot;,chardata&quot;`
  11. }
  12. e := entry{}
  13. doc.Elems = map[string]string{}
  14. for err = d.Decode(&amp;e); err == nil; err = d.Decode(&amp;e) {
  15. doc.Elems[e.Key] = e.Value
  16. }
  17. if err != nil &amp;&amp; err != io.EOF {
  18. return err
  19. }
  20. return nil
  21. }

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

huangapple
  • 本文由 发表于 2017年3月10日 22:53:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/42721278.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定