我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Golang xml 键名称冲突

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Golang xml 键名称冲突

问题内容

我需要生成一个复杂的 xml 文件才能将其加载到另一个系统中。因此,标签和标签顺序无法更改,因为它们必须遵循精确的格式才能正确加载。我目前正在 golang 中使用编码/xml 包来尝试完成此任务。

我遇到的问题是我不能有两个具有相同名称的标签。我收到以下错误: main.XMLDict 带有标签“key”的字段“Key1”与带有标签“key”的字段“Key2”冲突。下面是我的简化代码:

import (
    "fmt"
    "encoding/xml"
    "os"
)

type XMLDict struct {
    XMLName xml.Name    `xml:"dict"`
    Key1    string      `xml:"key"`
    Data1   string      `xml:"data"`
    Key2    string      `xml:"key"`
    StringArray XMLStringArray
}

type XMLStringArray struct {
    XMLName  xml.Name    `xml:"array"̀`
    XMLString   []string `xml:"string"`
}

func main() {

    sa := make([]string, 3)
    sa[0] = "g"
    sa[1] = "h"
    sa[2] = "i"

    arr := XMLStringArray{
        XMLString: sa,
    }

    master := XMLDict{
        Key1: "Color",
        Data1: "Random data",
        Key2: "Curve",
        StringArray: arr,
    }

    output, err := xml.MarshalIndent(master, "  ", "    ")
    if err != nil {
        fmt.Printf("error: %v\n", err)
    }

    os.Stdout.Write(output)

    return 
}

下面是我需要生成的 XML 文件的示例:


            Color
            
            BAtzdHJlYW10eXBlZIHoA4QBQISEhAdOU0NvbG9yAISECE5TT2Jq
            ZWN0AIWEAWMChARmZmZmg7oehT2DZmYmP4NmZiY/AYY=
            
            Curve
            
                Interpolation
                5
                Points
                
                    {0, 0}
                    {0.05, 0.053871}
                    {0.1, 0.110555}
                    {0.15, 0.166793}
                    {0.2, 0.216919}
                    {0.3, 0.327703}
                    {0.4, 0.440897}
                    {0.5, 0.539322}
                    {0.6, 0.657477}
                    {0.7, 0.763339}
                    {0.75, 0.814082}
                    {0.8, 0.861097}
                    {0.85, 0.904147}
                    {0.9, 0.944079}
                    {0.95, 0.974036}
                    {0.98, 0.990085}
                    {1, 1}
                
            
            Line Width
            0.0040000001899898052
            Points Diameter
            0.014999999664723873
            Precision
            9.9999997473787516e-05
        

所以,我的问题:1)有没有一种简单的方法来解决这个问题,仍然使用构建数据然后生成 XML 的结构方法,2)有没有更好的方法来构建和生成这个文件比使用 Stuts 或 3)我只是做错了什么吗?

编辑:下面是所请求的输入文件:

"File created by Curve"
LGOROWLENGTH 3
#
# Curve4 Run Information
#
# Run: Run 1 - Calibration
# Based On: 
#
# Values in this file are 'Wanted'
#
# Gray Balance: On
#    reduced after 100%
#    until 100%
#    media white values: Measured
#    media aim points: -0.17 / 0.96
#
NUMBER_OF_FIELDS    6
BEGIN_DATA_FORMAT
SampleID    SAMPLE_NAME CMYK_C  CMYK_M  CMYK_Y  CMYK_K
END_DATA_FORMAT
NUMBER_OF_SETS 17
BEGIN_DATA
A0  "0.00"  0.0000  0.0000  0.0000  0.0000
A1  "5.00"  5.3871  5.1408  5.2761  5.5775
A2  "10.00" 11.0555 10.7418 10.6026 11.0702
A3  "15.00" 16.6793 16.3894 15.8763 16.7064
A4  "20.00" 21.6919 21.7968 21.0234 22.3956
A5  "30.00" 32.7703 32.7458 31.1841 33.6738
A6  "40.00" 44.0897 42.4801 40.0887 44.2966
A7  "50.00" 53.9322 54.2364 49.1680 54.8968
A8  "60.00" 65.7477 64.9423 59.1719 66.4696
A9  "70.00" 76.3339 75.4398 69.4943 77.1661
A10 "75.00" 81.4082 80.5957 75.1423 82.0637
A11 "80.00" 86.1097 84.9296 81.1298 86.7399
A12 "85.00" 90.4147 88.8039 86.7945 90.8142
A13 "90.00" 94.4079 92.6783 92.1110 94.2426
A14 "95.00" 97.4036 96.2097 96.6019 97.2088
A15 "98.00" 99.0085 98.5775 98.7747 98.9000
A16 "100.00"    100.0000    100.0000    100.0000    100.0000
END_DATA


正确答案


我认为,有很多解决方案可以使用 XML 自定义封送拆收器来实现此目的;这是我的尝试。

首先,在你的根 中,它似乎总是这样的项目“列表”:

a-string
a-value

another-string
another-value

为了表示其中的每一个,我们可以定义一个 KeyValue 结构,其中 Value 只是一个接口来表示它可以容纳的任何内容(datainteger,...)

type KeyValue struct {
    Key   string
    Value Value
}

type Value interface {
    getXMLName() string // this will return data, integer, array, etc, depending on the implementation
}

然后,我们可以使用示例中提供的不同类型来实现 Value

type ValueData struct {
    Data string `xml:",chardata"`
}

func (v ValueData) getXMLName() string { return "data" }

type ValueInteger struct {
    Integer int `xml:",chardata"`
}

func (v ValueInteger) getXMLName() string { return "integer" }

type ValueStringArray struct {
    Array []string `xml:"string"`
}

func (v ValueStringArray) getXMLName() string { return "array" }

type ValueReal struct {
    Real float64 `xml:",chardata"`
}

func (v ValueReal) getXMLName() string { return "real" }

在 XML 标签内,chardata 用于避免在我们的 XML 文档中包含额外的级别;对于 ValueStringArray,我们使用 string 因为您的项目是这样命名的。

最后,为了允许递归(dict 内部 dict),我们还可以定义这个结构体:

type ValueDict struct {
    XMLName    xml.Name `xml:"dict"`
    KeysValues []KeyValue
}

func (v ValueDict) getXMLName() string { return "dict" }

完成所有操作后,我们就可以实现一个自定义封送拆收器:

func (kv KeyValue) MarshalXML(e *xml.Encoder, _ xml.StartElement) error {
    if err := e.EncodeElement(kv.Key, xml.StartElement{Name: xml.Name{Local: "key"}}); err != nil {
        return err
    }
    if err := e.EncodeElement(kv.Value, xml.StartElement{Name: xml.Name{Local: kv.Value.getXMLName()}}); err != nil {
        return err
    }
    return nil
}

这将允许生成如下项目:

Line Width
0.004000000189989805

标签的名称(此处为 real)基于 getXMLName() 方法返回的内容。

最后,您可以像这样定义 Go 结构体和元帅:

master := ValueDict{
    KeysValues: []KeyValue{
        {
            Key: "Color",
            Value: ValueData{
                Data: "BAtzdHJlYW10eXBlZIHoA4QBQISEhAdOU0NvbG9yAISECE5TT2JqZWN0AIWEAWMChARmZmZmg7oehT2DZmYmP4NmZiY/AYY=",
            },
        },
        {
            Key: "Curve",
            Value: ValueDict{
                KeysValues: []KeyValue{
                    {
                        Key: "Interpolation",
                        Value: ValueInteger{
                            Integer: 5,
                        },
                    },
                    {
                        Key: "Points",
                        Value: ValueStringArray{
                            Array: []string{
                                "{0, 0}",
                                "{0.05, 0.053871}",
                                "{0.1, 0.110555}",
                                "{0.15, 0.166793}",
                                "{0.2, 0.216919}",
                                "{0.3, 0.327703}",
                                "{0.4, 0.440897}",
                                "{0.5, 0.539322}",
                                "{0.6, 0.657477}",
                                "{0.7, 0.763339}",
                                "{0.75, 0.814082}",
                                "{0.8, 0.861097}",
                                "{0.85, 0.904147}",
                                "{0.9, 0.944079}",
                                "{0.95, 0.974036}",
                                "{0.98, 0.990085}",
                                "{1, 1}",
                            },
                        },
                    },
                },
            },
        },
        {
            Key: "Line Width",
            Value: ValueReal{
                Real: 0.0040000001899898052,
            },
        },
        {
            Key: "Points Diameter",
            Value: ValueReal{
                Real: 0.014999999664723873,
            },
        },
        {
            Key: "Precision",
            Value: ValueReal{
                Real: 9.9999997473787516e-05,
            },
        },
    },
}

output, err := xml.MarshalIndent(master, "  ", "    ")
if err != nil {
    fmt.Printf("error: %v\n", err)
}

os.Stdout.Write(output)

这将准确打印您问题中提供的示例 XML 中的内容。

您可以在 Go Playground 中测试完整代码:https://go.dev/play/p /k8cEIywx3UB。

该解决方案的主要优点是:

  • 我们只需要实现一个自定义 XML 封送拆收器
  • 如果您的 XML 文档中有其他结构(假设是一个布尔值,我们可以创建一个 ValueBool 实现 Value),则可以轻松扩展它

以上就是Golang xml 键名称冲突的详细内容,更多请关注编程网其它相关文章!

Golang xml 键名称冲突

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Golang xml 键名称冲突

问题内容我需要生成一个复杂的 xml 文件才能将其加载到另一个系统中。因此,标签和标签顺序无法更改,因为它们必须遵循精确的格式才能正确加载。我目前正在 golang 中使用编码/xml 包来尝试完成此任务。我遇到的问题是我不能有两个具有
Golang xml 键名称冲突
2024-02-05

golang 函数名称如何处理命名冲突?

go 中函数名称必须在同一包内唯一。若发生命名冲突,可使用以下策略处理:使用限定名:由包名和函数名组成,如:package main; import "fmt"; func printhello() { fmt.println("hello
golang 函数名称如何处理命名冲突?
2024-04-23

如何解决lvm名称冲突

本篇文章为大家展示了如何解决lvm名称冲突,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Red Hat Enterprise Linux Server release 7.3 (Maipo)原磁盘v
2023-06-06

jQuery 名称冲突的解决方法

jQuery 使用 $ 符号作为 jQuery 的简介方式。某些其他 JavaScript 库中的函数(比如 Prototype)同样使用 $ 符号。
2022-11-21

springboot生成bean名称冲突怎么解决

本篇内容介绍了“springboot生成bean名称冲突怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!springboot生成bea
2023-06-29

golang如何处理函数签名冲突?

go 处理函数签名冲突的方法:1. 使用接口定义共享签名的函数的不同实现;2. 使用别名重命名函数调用中的参数;3. 使用闭包创建具有共享变量的不同签名的函数。Go 中处理函数签名冲突Go 语言允许函数具有相同名称但参数类型不同的重载,这
golang如何处理函数签名冲突?
2024-04-29

冲突问题:Golang中的protobufs命名问题

对于一个Golang开发者来说,牢固扎实的基础是十分重要的,编程网就来带大家一点点的掌握基础知识点。今天本篇文章带大家了解《冲突问题:Golang中的protobufs命名问题》,主要介绍了,希望对大家的知识积累有所帮助,快点收藏起来吧,否
冲突问题:Golang中的protobufs命名问题
2024-04-05

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录