使用冲突的元素名称解压缩Go中的XML

时间:2015-03-10 00:52:25

标签: xml encoding go marshalling unmarshalling

我有以下XML,外部定义并且在我的组织控制之外:

<foo>
  <bar>
    <zip>zip</zip>
  </bar>
  <bar>
    <zap>zap</zap>
  </bar>
</foo>

我正在使用这些结构:

type Foo struct {
    XMLName xml.Name `xml:"foo"`
    Bar1    Bar1
    Bar2    Bar2
}

type Bar1 struct {
    XMLName xml.Name `xml:"bar"`
    Zip     string   `xml:"zip"`
}

type Bar2 struct {
    XMLName xml.Name `xml:"bar"`
    Zap     string   `xml:"zap"`
}

由于'bar'名称冲突,所以没有任何内容被拆开。如何填充Bar1和Bar2结构?

这就是我所拥有的:https://play.golang.org/p/D2IRLojcTB

这是我想要的结果:https://play.golang.org/p/Ytrbzzy9Ok

在第二个中,我将第二个'bar'更新为'bar1',这一切都有效。我宁愿想出一个更清晰的解决方案来修改传入的XML。

1 个答案:

答案 0 :(得分:10)

encoding/xml软件包无法完全按照您的要求执行操作,因为它会在Foo遇到<bar>时解析xml.Unmarshal哪个字段进行解码元素,而不是处理该元素的子元素。您的结构定义使得此决策不明确,因为来自Bar的错误表明:

  

main.Foo field&#34; Bar1&#34;标签&#34;&#34;与领域冲突&#34; Bar2&#34;标签&#34;&#34;

以下两种方法可行:

<强> 1。使用一个type Foo struct { XMLName xml.Name `xml:"foo"` Bars []Bar `xml:"bar"` } type Bar struct { Zip string `xml:"zip"` Zap string `xml:"zap"` } 结构来涵盖两个分支

如果您将类型修改为:

<bar>

现在,您将获得一个代表所有<zip>元素的切片。您可以通过检查相应字段是否为空来判断该元素是否具有<zap><bar>元素。

您可以在此处试用此版本:https://play.golang.org/p/kguPCYmKX0

<强> 2。使用子选择器

如果您只对每个分支中的type Foo struct { XMLName xml.Name `xml:"foo"` Zip string `xml:"bar>zip"` Zap string `xml:"bar>zap"` } 的单个子元素感兴趣,那么您可能根本不需要结构来表示该元素。例如,您可以解码为以下类型:

<bar>

现在,Foo元素的子元素将直接解码为<foo> <bar> <zip>zip</zip> <zap>zap</zap> </bar> </foo> 结构的成员。请注意,使用此选项,您无法区分所选输入,例如

{{1}}

如果这会导致问题,那么你应该选择第一个解决方案。

您可以在此处试用此版本:https://play.golang.org/p/fAE_HSrv4y