为了账号安全,请及时绑定邮箱和手机立即绑定

使用 Golang 进行 XML 编组 - 具有相同节点名称的多个节点

使用 Golang 进行 XML 编组 - 具有相同节点名称的多个节点

Go
冉冉说 2021-11-29 16:37:26
在VAST规范中,一个 XML 文件可能包含多个具有相同名称的节点 - 例如,多个Impression节点的不同之处仅在于它们的id.考虑以下示例:<?xml version="1.0" encoding="UTF-8"?><VAST xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0" xsi:noNamespaceSchemaLocation="vast.xsd">   <Ad id="812030">      <InLine>         <AdSystem>FT</AdSystem>         <AdTitle>Flashtalking mobile vast template 2.0</AdTitle>         <Description>date of revision 10-04-14</Description>         <Impression id="ft_vast_i"><![CDATA[http://servedby.flashtalking.com/imp/1/31714;812030;201;gif;DailyMail;640x360VASTHTML5/?ft_creative=377314&ft_configuration=0&cachebuster=1076585830]]></Impression>         <Impression id="3rdparty" />         <Impression id="3rdparty" />         <Impression id="3rdparty" />         <Impression id="3rdparty" />         <Impression id="3rdparty" />         <Impression id="3rdparty" />         <Creatives>            <Creative sequence="1">               <Linear>                  <Duration>00:00:15</Duration>                  <TrackingEvents>                  </TrackingEvents>                  <VideoClicks>                  </VideoClicks>                  <MediaFiles>                  </MediaFiles>               </Linear>            </Creative>            <Creative sequence="1">               <CompanionAds />            </Creative>         </Creatives>      </InLine>   </Ad></VAST>注意多个Impression节点,它们的不同之处仅在于它们的id属性(事实上,有时甚至可能是相同的)。有没有办法用 Golang 来表示这种结构,以保持使用encoding/xml包对 xml 进行编组和解组的能力?
查看完整描述

2 回答

?
蛊毒传说

TA贡献1895条经验 获得超3个赞

对于重复的 XML 标签,只需在 Go 中使用切片即可。


请参阅这个简单的示例,它处理您的 XML 输入,重点是解组<Impression>标签,然后再次对其进行编组:


type Impression struct {

    Id      string `xml:"id,attr"`

    Content string `xml:",chardata"`

}


type VAST struct {

    Impressions []Impression `xml:"Ad>InLine>Impression"`

}


func main() {

    v := &VAST{}

    if err := xml.Unmarshal([]byte(src), v); err != nil {

        panic(err)

    }

    fmt.Printf("%+v\n\n", v)


    if out, err := xml.MarshalIndent(v, "", "  "); err != nil {

        panic(err)

    } else {

        fmt.Println(string(out))

    }

}

输出(已包装,在Go Playground上尝试):


&{Impressions:[{Id:ft_vast_i Content:http://servedby.fla...[CUT]...1076585830} 

{Id:3rdparty Content:} {Id:3rdparty Content:} {Id:3rdparty Content:} 

{Id:3rdparty Content:} {Id:3rdparty Content:} {Id:3rdparty Content:}]}


<VAST>

  <Ad>

    <InLine>

      <Impression id="ft_vast_i">http://servedby.fla...[CUT]...1076585830</Impression>

      <Impression id="3rdparty"></Impression>

      <Impression id="3rdparty"></Impression>

      <Impression id="3rdparty"></Impression>

      <Impression id="3rdparty"></Impression>

      <Impression id="3rdparty"></Impression>

      <Impression id="3rdparty"></Impression>

    </InLine>

  </Ad>

</VAST>


查看完整回答
反对 回复 2021-11-29
?
鸿蒙传说

TA贡献1865条经验 获得超7个赞

是的,您可以编组/解组多个具有相同名称的节点。只需使用切片。


看一下例子中的Email切片encoding/xml:


type Email struct {

    Where string `xml:"where,attr"`

    Addr  string

}

type Address struct {

    City, State string

}

type Result struct {

    XMLName xml.Name `xml:"Person"`

    Name    string   `xml:"FullName"`

    Phone   string

    Email   []Email

    Groups  []string `xml:"Group>Value"`

    Address

}

以及相应的 XML 文档:


<Person>

  <FullName>Grace R. Emlin</FullName>

  <Company>Example Inc.</Company>

  <Email where="home">

    <Addr>gre@example.com</Addr>

  </Email>

  <Email where='work'>

    <Addr>gre@work.com</Addr>

  </Email>

  <Group>

    <Value>Friends</Value>

    <Value>Squash</Value>

  </Group>

  <City>Hanga Roa</City>

  <State>Easter Island</State>

</Person>


查看完整回答
反对 回复 2021-11-29
  • 2 回答
  • 0 关注
  • 154 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信