You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言反序列化带编号XML标签问题求助

解决Go XML反序列化问题:提取Setting名称与Register值

原代码核心问题

  1. 反序列化目标错误:XML根节点是单个<Settings>,但你用了[]SettingContainer切片接收,导致无法正确解析内部节点。
  2. 缺少节点过滤逻辑:现有结构体仅接收所有节点,无法精准筛选出SettingN_register类型的节点。

方案一:调整结构体+解析后过滤

这种方式实现简单,先完整解析XML,再提取所需字段:

package main

import (
    "bytes"
    "encoding/xml"
    "fmt"
    "strings"
)

type SettingContainer struct {
    XMLName  xml.Name  `xml:"Settings"`
    Settings []Setting `xml:",any"`
}

type Setting struct {
    XMLName xml.Name `xml:",any"`
    // 接收SettingN下的所有子节点
    Children []SettingRegister `xml:",any"`
}

type SettingRegister struct {
    XMLName xml.Name `xml:",any"`
    Value   string   `xml:"value,attr"`
}

func main() {
    var xmlData = bytes.NewBufferString(`
    <Settings>
        <Setting0>
            <Setting0_register value="0x20" />
            <Setting0ArbitraryName value="0x0" />
        </Setting0>
        <Setting1>
            <Setting1_register value="0x60" />
            <Setting1WhateverEnable value="0x0" />
        </Setting1>
        <Setting2>
            <Setting2_register value="0x80" />
            <Setting2blahblah value="0x1" />
        </Setting2>
        <Setting4>
            <Setting4_register value="0x2fffff8" />
            <Setting4ThisCanBeAnything value="0x0" />
        </Setting4>
    </Settings>`)

    var s SettingContainer
    if err := xml.Unmarshal(xmlData.Bytes(), &s); err != nil {
        fmt.Printf("解析错误:%v\n", err)
        return
    }

    // 遍历提取所需数据
    for _, setting := range s.Settings {
        settingName := setting.XMLName.Local
        for _, child := range setting.Children {
            if strings.HasSuffix(child.XMLName.Local, "_register") {
                fmt.Printf("Setting名称:%s,Register值:%s\n", settingName, child.Value)
                break // 每个Setting下仅一个_register节点,找到即退出循环
            }
        }
    }
}

方案二:自定义UnmarshalXML方法(高效过滤)

直接在反序列化阶段筛选目标节点,减少后续处理开销:

package main

import (
    "bytes"
    "encoding/xml"
    "fmt"
    "io"
    "strings"
)

type SettingData struct {
    SettingName string
    RegisterVal string
}

type Settings struct {
    XMLName xml.Name      `xml:"Settings"`
    Items   []SettingData `xml:",any"`
}

// 自定义SettingData的反序列化方法,直接提取所需字段
func (sd *SettingData) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
    sd.SettingName = start.Name.Local

    // 遍历SettingN下的所有子节点
    for {
        var elem xml.StartElement
        err := d.Decode(&elem)
        if err != nil {
            if err == io.EOF {
                break
            }
            return err
        }

        // 只处理_register结尾的节点
        if strings.HasSuffix(elem.Name.Local, "_register") {
            // 提取value属性
            for _, attr := range elem.Attr {
                if attr.Name.Local == "value" {
                    sd.RegisterVal = attr.Value
                    break
                }
            }
            // 跳过当前节点的结束标签
            if err := d.Skip(); err != nil {
                return err
            }
        } else {
            // 跳过非目标节点
            if err := d.Skip(); err != nil {
                return err
            }
        }
    }
    return nil
}

func main() {
    var xmlData = bytes.NewBufferString(`
    <Settings>
        <Setting0>
            <Setting0_register value="0x20" />
            <Setting0ArbitraryName value="0x0" />
        </Setting0>
        <Setting1>
            <Setting1_register value="0x60" />
            <Setting1WhateverEnable value="0x0" />
        </Setting1>
        <Setting2>
            <Setting2_register value="0x80" />
            <Setting2blahblah value="0x1" />
        </Setting2>
        <Setting4>
            <Setting4_register value="0x2fffff8" />
            <Setting4ThisCanBeAnything value="0x0" />
        </Setting4>
    </Settings>`)

    var s Settings
    if err := xml.Unmarshal(xmlData.Bytes(), &s); err != nil {
        fmt.Printf("解析错误:%v\n", err)
        return
    }

    for _, item := range s.Items {
        fmt.Printf("Setting名称:%s,Register值:%s\n", item.SettingName, item.RegisterVal)
    }
}

内容的提问来源于stack exchange,提问作者Arrrow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 20:34:56