冲突的键名称在Golang的XML中的问题
来源:stackoverflow
时间:2024-02-05 08:20:49 409浏览 收藏
Golang不知道大家是否熟悉?今天我将给大家介绍《冲突的键名称在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-valueanother-string another-value
为了表示其中的每一个,我们可以定义一个 KeyValue
结构,其中 Value
只是一个接口来表示它可以容纳的任何内容(data
,integer
,...)
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学习网公众号,带你了解更多关于的知识点!
-
502 收藏
-
502 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
139 收藏
-
204 收藏
-
325 收藏
-
477 收藏
-
486 收藏
-
439 收藏
-
357 收藏
-
352 收藏
-
101 收藏
-
440 收藏
-
212 收藏
-
143 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 508次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习