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

XML 通过字段名称中的索引解组动态响应

XML 通过字段名称中的索引解组动态响应

Go
12345678_0001 2023-07-26 17:23:09
我正在尝试解组“动态”XML 响应,但我不确定如何处理它。服务器响应相当大的响应,所以我不想两次解析响应。XML 看起来像这样:...<nic_cnt>2</nic_cnt><ifindex1>eno1</ifindex1><ifindex2>eno2</ifindex2>...因此该字段定义了发生的nic_cnt次数。ifindex由于我不知道会发生多少次ifindex,因此我无法静态定义解组响应所需的结构字段。
查看完整描述

1 回答

?
慕标琳琳

TA贡献1830条经验 获得超9个赞

您可以使用带有 XML 标记选项的切片,any来告诉encoding/xml包将任何 XML 标记放入其中。这记录在xml.Unmarshal()

If the XML element contains a sub-element that hasn't matched any

   of the above rules and the struct has a field with tag ",any",

   unmarshal maps the sub-element to that struct field.

对于<ifindexXX>标签,使用另一个包含XMLNametype 字段的结构xml.Name,因此如果您需要仅过滤以 开头的字段,则实际字段名称将可用ifindex。


让我们解析以下 XML:


<root>

    <nic_cnt>2</nic_cnt>

    <ifindex1>eno1</ifindex1>

    <ifindex2>eno2</ifindex2>

</root>

我们可以用以下方法对其进行建模:


type Root struct {

    NicCnt  int     `xml:"nic_cnt"`

    Entries []Entry `xml:",any"`

}


type Entry struct {

    XMLName xml.Name

    Value   string `xml:",innerxml"`

}

解析它的示例代码:


var root Root

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

    panic(err)

}

fmt.Printf("%+v", root)

输出(在Go Playground上尝试):


{NicCnt:2 Entries:[

    {XMLName:{Space: Local:ifindex1} Value:eno1}

    {XMLName:{Space: Local:ifindex2} Value:eno2}]}

请注意,Root.Entries还将包含其他未映射的 XML 标记。如果您只关心以 开头的标签ifindex,则可以通过以下方式“过滤”它们:


for _, e := range root.Entries {

    if strings.HasPrefix(e.XMLName.Local, "ifindex") {

        fmt.Println(e.XMLName.Local, ":", e.Value)

    }

}

如果 XML 还包含附加标签:


<other>something else</other>

输出将是(在Go Playground上尝试这个):


{NicCnt:2 Entries:[

    {XMLName:{Space: Local:ifindex1} Value:eno1}

    {XMLName:{Space: Local:ifindex2} Value:eno2}

    {XMLName:{Space: Local:other} Value:something else}]}

ifindex1 : eno1

ifindex2 : eno2


查看完整回答
反对 回复 2023-07-26
  • 1 回答
  • 0 关注
  • 107 浏览
慕课专栏
更多

添加回答

举报

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