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

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

Go Parse XML to struct by tag attribute

问题

我正在尝试按属性和值解析以下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"
            }
          ]

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

英文:

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

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

I've come up with the following

type Response struct {
	StrDoc []Str `xml:&quot;result&gt;doc&quot;`
}

type Str struct {
	Doc   []Doc   `xml:&quot;str&quot;`
	Score []Score `xml:&quot;float&quot;`
}

type Doc struct {
	Key   string `xml:&quot;name,attr&quot;`
	Value string `xml:&quot;,chardata&quot;`
}

type Score struct {
	Score string `xml:&quot;,chardata&quot;`
}

which produces

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

The desired output would be

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

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

答案1

得分: 3

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

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-

英文:

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

type Result struct {
	Doc Doc `xml:&quot;doc&quot;`
}

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:&quot;name,attr&quot;`
		Value string `xml:&quot;,chardata&quot;`
	}
	e := entry{}
	doc.Elems = map[string]string{}
	for err = d.Decode(&amp;e); err == nil; err = d.Decode(&amp;e) {
		doc.Elems[e.Key] = e.Value
	}
	if err != nil &amp;&amp; err != io.EOF {
		return err
	}
	return nil
}

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:

确定