在Go语言中解析XML并处理重复标签的方法

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

xml parsing in go with repetitive tags

问题

当一个 XML feed 在结构中有多个标签时,我在解析它时遇到了问题:

<feed>
<entry>
:
:
</entry>
<entry>
:
:

</entry>
</feed>

在这种情况下,我通过定义一个 []entries 数组来解析 entry,没有问题。
然而,其中一个 entry 是一个 geocode 标签,它的 valuename 和 value 标签重复出现两次。在这种情况下,如何定义一个结构呢?

<geocode>
<valueName>abc</valueName>
<value>a1</value>
<valueName>def</valueName>
<value>d1</value>
</geocode>

这是我在使用的 Go 程序遇到问题的链接:
https://play.golang.org/p/SE8RXTNbYl

英文:

When an xml feed has multiple tags within a structure I am having issues parsing it:

&lt;feed&gt;
&lt;entry&gt;
:
:
&lt;/entry&gt;
&lt;entry&gt;
:
:

&lt;/entry&gt;
&lt;/feed&gt;

In this case I have no issues parsing the entry by defining an array of []entries
However one of the entries is a geocode tag which has valuename and value tag repeated twice. How does one define a structure in such a case.?

&lt;geocode&gt;
&lt;valueName&gt;abc&lt;/valueName&gt;
&lt;value&gt;a1&lt;/value&gt;
&lt;valueName&gt;def&lt;/valueName&gt;
&lt;value&gt;d1&lt;/value&gt;
&lt;/geocode&gt;

Here is the go program that I am having issues with
https://play.golang.org/p/SE8RXTNbYl

答案1

得分: 7

如果在同一个父标签下有多个具有相同名称的标签,您可以始终使用一个切片来保存所有出现的标签,无论它们是连续枚举的还是它们之间有其他标签。

为了完整起见,这是您要解析的 XML 片段:

<cap:geocode>
	<valueName>FIPS6</valueName>
	<value>002090 002290</value>
	<valueName>UGC</valueName>
	<value>AKZ222</value>
</cap:geocode>

所以只需将您的 geocode 结构从这个:

type geocode struct {
	ValueName1 string `xml:"valueName"`
	Value1     string `xml:"value"`
	ValueName2 string `xml:"valueName"`
	Value2     string `xml:"value"`
}

改为这个:

type geocode struct {
	ValueNames []string `xml:"valueName"`
	Values     []string `xml:"value"`
}

并编写代码来打印它们:

gc := v.Entries[0].Geocode
log.Println(len(gc.Values))
log.Println(gc.ValueNames)
log.Println(gc.Values)
for i := range gc.Values {
	fmt.Printf("ValueName=%s, Value=%s\n", gc.ValueNames[i], gc.Values[i])
}

输出结果(在 Go Playground 上尝试您修改后的源代码):

2009/11/10 23:00:00 2
2009/11/10 23:00:00 [FIPS6 UGC]
2009/11/10 23:00:00 [002090 002290 AKZ222]
ValueName=FIPS6, Value=002090 002290
ValueName=UGC, Value=AKZ222
英文:

If you have multiple tags with the same name under the same parent tag, you can always use a slice which will hold all the occurrences of the tag, regardless if they are enumerated next to each other or there are other tags between them.

To be complete, this is the XML fragment you want to parse:

&lt;cap:geocode&gt;
	&lt;valueName&gt;FIPS6&lt;/valueName&gt;
	&lt;value&gt;002090 002290&lt;/value&gt;
	&lt;valueName&gt;UGC&lt;/valueName&gt;
	&lt;value&gt;AKZ222&lt;/value&gt;
&lt;/cap:geocode&gt;

So simply change your geocode struct from this:

type geocode struct {
	ValueName1 string `xml:&quot;valueName&quot;`
	Value1     string `xml:&quot;value&quot;`
	ValueName2 string `xml:&quot;valueName&quot;`
	Value2     string `xml:&quot;value&quot;`
}

To this:

type geocode struct {
	ValueNames []string `xml:&quot;valueName&quot;`
	Values     []string `xml:&quot;value&quot;`
}

And code to print them:

gc := v.Entries[0].Geocode
log.Println(len(gc.Values))
log.Println(gc.ValueNames)
log.Println(gc.Values)
for i := range gc.Values {
	fmt.Printf(&quot;ValueName=%s, Value=%s\n&quot;, gc.ValueNames[i], gc.Values[i])
}

Output (try your modified source on the Go Playground):

2009/11/10 23:00:00 2
2009/11/10 23:00:00 [FIPS6 UGC]
2009/11/10 23:00:00 [002090 002290 AKZ222]
ValueName=FIPS6, Value=002090 002290
ValueName=UGC, Value=AKZ222

huangapple
  • 本文由 发表于 2016年1月19日 03:55:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/34862991.html
匿名

发表评论

匿名网友

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

确定