0

0

Golang xml 键名称冲突

WBOY

WBOY

发布时间:2024-02-05 22:03:04

|

787人浏览过

|

来源于stackoverflow

转载

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)我只是做错了什么吗?

立即学习go语言免费学习笔记(深入)”;

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

"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

Python之模块学习 中文WORD版
Python之模块学习 中文WORD版

本文档主要讲述的是Python之模块学习;python是由一系列的模块组成的,每个模块就是一个py为后缀的文件,同时模块也是一个命名空间,从而避免了变量名称冲突的问题。模块我们就可以理解为lib库,如果需要使用某个模块中的函数或对象,则要导入这个模块才可以使用,除了系统默认的模块(内置函数)不需要导入外。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看

下载
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),则可以轻松扩展它

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

178

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

226

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

337

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

208

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

388

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

194

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

189

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

192

2025.06.17

Java 项目构建与依赖管理(Maven / Gradle)
Java 项目构建与依赖管理(Maven / Gradle)

本专题系统讲解 Java 项目构建与依赖管理的完整体系,重点覆盖 Maven 与 Gradle 的核心概念、项目生命周期、依赖冲突解决、多模块项目管理、构建加速与版本发布规范。通过真实项目结构示例,帮助学习者掌握 从零搭建、维护到发布 Java 工程的标准化流程,提升在实际团队开发中的工程能力与协作效率。

10

2026.01.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号