I need to generate a complex xml file in order to load it into another system. Therefore, tags and tag order cannot be changed as they must follow a precise format to load correctly. I'm currently using the encoding/xml package in golang to try to accomplish this.
The problem I'm having is that I can't have two tags with the same name. I get the following error: main.XMLDict Field "Key1" with label "key" conflicts with field "Key2" with label "key". Below is my simplified code:
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 }
Here is an example of the XML file I need to generate:
<dict> <key>Color</key> <data> BAtzdHJlYW10eXBlZIHoA4QBQISEhAdOU0NvbG9yAISECE5TT2Jq ZWN0AIWEAWMChARmZmZmg7oehT2DZmYmP4NmZiY/AYY= </data> <key>Curve</key> <dict> <key>Interpolation</key> <integer>5</integer> <key>Points</key> <array> <string>{0, 0}</string> <string>{0.05, 0.053871}</string> <string>{0.1, 0.110555}</string> <string>{0.15, 0.166793}</string> <string>{0.2, 0.216919}</string> <string>{0.3, 0.327703}</string> <string>{0.4, 0.440897}</string> <string>{0.5, 0.539322}</string> <string>{0.6, 0.657477}</string> <string>{0.7, 0.763339}</string> <string>{0.75, 0.814082}</string> <string>{0.8, 0.861097}</string> <string>{0.85, 0.904147}</string> <string>{0.9, 0.944079}</string> <string>{0.95, 0.974036}</string> <string>{0.98, 0.990085}</string> <string>{1, 1}</string> </array> </dict> <key>Line Width</key> <real>0.0040000001899898052</real> <key>Points Diameter</key> <real>0.014999999664723873</real> <key>Precision</key> <real>9.9999997473787516e-05</real> </dict>
So, my questions: 1) Is there an easy way to solve this problem, still using the structural approach of building the data and then generating the XML, 2) Is there a better way to build and generate this file than using Stuts or 3) Am I just doing something wrong?
EDIT: Below is the requested input file:
"File created by Curve" LGOROWLENGTH 3 # # Curve4 Run Information # # Run: Run 1 - Calibration # Based On: <none> # # 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
Correct answer
I think there are many solutions to achieve this using XML custom marshaler; this is my attempt.
First of all, in your root <dict></dict>
it always seems to be a "list" of items like this:
<key>a-string</key> <data|integer|real|array|dict>a-value</data|integer|real|array|dict> <key>another-string</key> <data|integer|real|array|dict>another-value</data|integer|real|array|dict>
To represent each of these, we can define a KeyValue
structure, where Value
is just an interface to represent anything it can hold (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 }
We can then implement Value
using the different types provided in the example:
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" }
Within the XML tag, chardata
is used to avoid including extra levels in our XML document; for ValueStringArray
, we use string
because your The project is named this way.
Finally, to allow recursion (dict
internal dict
), we can also define this structure:
type ValueDict struct { XMLName xml.Name `xml:"dict"` KeysValues []KeyValue } func (v ValueDict) getXMLName() string { return "dict" }
After completing all operations, we can implement a custom marshaler:
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 }
This will allow the generation of projects like this:
<key>Line Width</key> <real>0.004000000189989805</real>The name of the
tag (here real
) is based on what is returned by the getXMLName()
method.
Finally, you can define Go structs and marshals like this:
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)
This will print exactly what is in the sample XML provided in your question.
You can test the complete code in the Go Playground: https://go.dev/play/p /k8cEIywx3UB.
The main advantages of this solution are:
- We just need to implement a custom XML marshaler
- It can be easily extended if you have other structures in your XML document (let's say a boolean value, we can create a
ValueBool
implementationValue
)
The above is the detailed content of Golang xml key name conflict. For more information, please follow other related articles on the PHP Chinese website!

Golang and C each have their own advantages in performance competitions: 1) Golang is suitable for high concurrency and rapid development, and 2) C provides higher performance and fine-grained control. The selection should be based on project requirements and team technology stack.

Golang is suitable for rapid development and concurrent programming, while C is more suitable for projects that require extreme performance and underlying control. 1) Golang's concurrency model simplifies concurrency programming through goroutine and channel. 2) C's template programming provides generic code and performance optimization. 3) Golang's garbage collection is convenient but may affect performance. C's memory management is complex but the control is fine.

Goimpactsdevelopmentpositivelythroughspeed,efficiency,andsimplicity.1)Speed:Gocompilesquicklyandrunsefficiently,idealforlargeprojects.2)Efficiency:Itscomprehensivestandardlibraryreducesexternaldependencies,enhancingdevelopmentefficiency.3)Simplicity:

C is more suitable for scenarios where direct control of hardware resources and high performance optimization is required, while Golang is more suitable for scenarios where rapid development and high concurrency processing are required. 1.C's advantage lies in its close to hardware characteristics and high optimization capabilities, which are suitable for high-performance needs such as game development. 2.Golang's advantage lies in its concise syntax and natural concurrency support, which is suitable for high concurrency service development.

Golang excels in practical applications and is known for its simplicity, efficiency and concurrency. 1) Concurrent programming is implemented through Goroutines and Channels, 2) Flexible code is written using interfaces and polymorphisms, 3) Simplify network programming with net/http packages, 4) Build efficient concurrent crawlers, 5) Debugging and optimizing through tools and best practices.

The core features of Go include garbage collection, static linking and concurrency support. 1. The concurrency model of Go language realizes efficient concurrent programming through goroutine and channel. 2. Interfaces and polymorphisms are implemented through interface methods, so that different types can be processed in a unified manner. 3. The basic usage demonstrates the efficiency of function definition and call. 4. In advanced usage, slices provide powerful functions of dynamic resizing. 5. Common errors such as race conditions can be detected and resolved through getest-race. 6. Performance optimization Reuse objects through sync.Pool to reduce garbage collection pressure.

Go language performs well in building efficient and scalable systems. Its advantages include: 1. High performance: compiled into machine code, fast running speed; 2. Concurrent programming: simplify multitasking through goroutines and channels; 3. Simplicity: concise syntax, reducing learning and maintenance costs; 4. Cross-platform: supports cross-platform compilation, easy deployment.

Confused about the sorting of SQL query results. In the process of learning SQL, you often encounter some confusing problems. Recently, the author is reading "MICK-SQL Basics"...


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

ZendStudio 13.5.1 Mac
Powerful PHP integrated development environment

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool

Dreamweaver CS6
Visual web development tools

VSCode Windows 64-bit Download
A free and powerful IDE editor launched by Microsoft

Dreamweaver Mac version
Visual web development tools