Namespace prefixes stripped out from XML element keys and attributes
Hey @clbanning ,
x2j.XmlToJson() when using this, the prefixes are stripping out from the xml elements, in json.
Is there anyway to handle this,
I even looked to #110 , but that is even getting to fail by getting this error : invalid attribute key label: #text - due to attributes not being prefixed when converting back to xml from the generated json.
Can you provide example to review?
Yeah, @clbanning Let's have,
data := `<ApiRequest
xmlns:xsi="http://www.w3.orgs/2001/XMLSchema-instance"
xmlns:xs="http://www.w3.orgs/2001/XMLSchema">
<ApiKey>eaal9R0n9rJ1GlhGgnas7E</ApiKey>
<VerboseErrors>true</VerboseErrors>
<ReturnData>true</ReturnData>
<Data xsi:type='Subscriber'>
<Mode>AddAndIgnore</Mode>
<Force>false</Force>
<ListId>18</ListId>
<Email>[email protected]</Email>
<Firstname>Samantha</Firstname>
<Lastname>Taylor</Lastname>
<Properties>
<Property>
<Id>1</Id>
<Value xsi:type="xs:string">40100989867</Value>
</Property>
</Properties>
</Data>
</ApiRequest>`
msv, _ := mxj.NewMapXmlSeq([]byte(data), true)
json, _ := json.Marshal(msv)
mv, _ := mxj.NewMapJson(json)
mv.Json(true)
msv = mxj.Map(mv)
xml, err := msv.Xml()
if err != nil {
fmt.Println(err)
}
fmt.Println(xml)
With this, I am getting error : invalid attribute key label: #text - due to attributes not being prefixed
And if I use
jsonData, _ := x2j.XmlToJson(string(data))
i am getting json data but the prefixes were missing
I'm running the following version of your example and everything is behaving as expected. (go1.17 darwin/amd64) Please edit this to reproduce the errors you reference.
`package main
import ( "encoding/json" "fmt"
"github.com/clbanning/mxj"
)
func main() {
data := <ApiRequest xmlns:xsi="http://www.w3.orgs/2001/XMLSchema-instance" xmlns:xs="http://www.w3.orgs/2001/XMLSchema"> <ApiKey>eaal9R0n9rJ1GlhGgnas7E</ApiKey> <VerboseErrors>true</VerboseErrors> <ReturnData>true</ReturnData> <Data xsi:type='Subscriber'> <Mode>AddAndIgnore</Mode> <Force>false</Force> <ListId>18</ListId> <Email>[email protected]</Email> <Firstname>Samantha</Firstname> <Lastname>Taylor</Lastname> <Properties> <Property> <Id>1</Id> <Value xsi:type="xs:string">40100989867</Value> </Property> </Properties> </Data> </ApiRequest>
msv, _ := mxj.NewMapXmlSeq([]byte(data), true)
fmt.Println("MapSeq val from data -")
fmt.Println(msv.StringIndentNoTypeInfo(3)) // the MapSeq val
js, _ := json.MarshalIndent(msv,"", " ")
fmt.Println("Json val from MapSeq val -")
fmt.Println(string(js))
mv, _ := mxj.NewMapJson(js) // unmarshal to Map val just calls stdlib
fmt.Println("Map val from Json val -")
fmt.Println(mv.StringIndentNoTypeInfo(3))
mv.Json(true) // what does this do?
// mv = mxj.Map(mv) // don't know what this is for
xml, err := mv.XmlIndent("", " ")
if err != nil {
fmt.Println(err)
}
fmt.Println("Xml val from Map val -")
fmt.Println(string(xml))
} `
Ooops, I think the issue is with my go version go1.21.3. I should try with that version you have mentioned.
Anyway thank you.
No. Do you get the same errors as before with go1.21.3? If you do, then I'll upgrade to the tip and relook at the results - something may have changed in stdlib. (I've not keep up with go versions for several years, obviously.)
Yes, I go the same errors with go1.21.3
Thanks. Give me a few days to look into this.
Just ran program I sent in previous comment with go1.21.12 darwin/amd64, and it ran as expected without error. So I'm a bit mystified about why you'd be getting errors - it successfully runs with go1.17.3, go1.19.3, and go1.21.12. Please run the code I provided and upload all the output including fmt.Println output and error messages.
Hey @clbanning ,
Apologies, for the delay in my response, here is the results of the code that I ran with the logs, you can check that, that Xml val from Map Val got failed, rest of 3 steps worked fine. Below are the complete results.
MapSeq val from data -
ApiRequest :
#attr :
xmlns:xs :
#seq : 1
#text : http://www.w3.orgs/2001/XMLSchema
xmlns:xsi :
#seq : 0
#text : http://www.w3.orgs/2001/XMLSchema-instance
ApiKey :
#seq : 0
#text : eaal9R0n9rJ1GlhGgnas7E
Data :
#attr :
xsi:type :
#seq : 0
#text : Subscriber
#seq : 3
Email :
#seq : 3
#text : [email protected]
Firstname :
#seq : 4
#text : Samantha
Force :
#seq : 1
#text : false
Lastname :
#seq : 5
#text : Taylor
ListId :
#seq : 2
#text : 18
Mode :
#seq : 0
#text : AddAndIgnore
Properties :
#seq : 6
Property :
#seq : 0
Id :
#seq : 0
#text : 1
Value :
#attr :
xsi:type :
#seq : 0
#text : xs:string
#seq : 1
#text : 4.0100989867e+10
ReturnData :
#seq : 2
#text : true
VerboseErrors :
#seq : 1
#text : true
Json val from MapSeq val -
{
"ApiRequest": {
"#attr": {
"xmlns:xs": {
"#seq": 1,
"#text": "http://www.w3.orgs/2001/XMLSchema"
},
"xmlns:xsi": {
"#seq": 0,
"#text": "http://www.w3.orgs/2001/XMLSchema-instance"
}
},
"ApiKey": {
"#seq": 0,
"#text": "eaal9R0n9rJ1GlhGgnas7E"
},
"Data": {
"#attr": {
"xsi:type": {
"#seq": 0,
"#text": "Subscriber"
}
},
"#seq": 3,
"Email": {
"#seq": 3,
"#text": "[email protected]"
},
"Firstname": {
"#seq": 4,
"#text": "Samantha"
},
"Force": {
"#seq": 1,
"#text": false
},
"Lastname": {
"#seq": 5,
"#text": "Taylor"
},
"ListId": {
"#seq": 2,
"#text": 18
},
"Mode": {
"#seq": 0,
"#text": "AddAndIgnore"
},
"Properties": {
"#seq": 6,
"Property": {
"#seq": 0,
"Id": {
"#seq": 0,
"#text": 1
},
"Value": {
"#attr": {
"xsi:type": {
"#seq": 0,
"#text": "xs:string"
}
},
"#seq": 1,
"#text": 40100989867
}
}
}
},
"ReturnData": {
"#seq": 2,
"#text": true
},
"VerboseErrors": {
"#seq": 1,
"#text": true
}
}
}
Map val from Json val -
ApiRequest :
#attr :
xmlns:xs :
#seq : 1
#text : http://www.w3.orgs/2001/XMLSchema
xmlns:xsi :
#seq : 0
#text : http://www.w3.orgs/2001/XMLSchema-instance
ApiKey :
#seq : 0
#text : eaal9R0n9rJ1GlhGgnas7E
Data :
#attr :
xsi:type :
#seq : 0
#text : Subscriber
#seq : 3
Email :
#seq : 3
#text : [email protected]
Firstname :
#seq : 4
#text : Samantha
Force :
#seq : 1
#text : false
Lastname :
#seq : 5
#text : Taylor
ListId :
#seq : 2
#text : 18
Mode :
#seq : 0
#text : AddAndIgnore
Properties :
#seq : 6
Property :
#seq : 0
Id :
#seq : 0
#text : 1
Value :
#attr :
xsi:type :
#seq : 0
#text : xs:string
#seq : 1
#text : 4.0100989867e+10
ReturnData :
#seq : 2
#text : true
VerboseErrors :
#seq : 1
#text : true
invalid attribute key label: #text - due to attributes not being prefixed
Xml val from Map val -
<ApiRequest>
<#attr>
<xmlns:xs
OK. I see a number of errors in the last encoding, though not what you have. First, by default mxj casts boolean-like values to boolean values which aren't getting re-encoded correctly after passing through the JSON encoding/decoding steps. (See, CastValuesToBool(...).)
Also, the JSON value encodes the MapSeq meta-keys, "#seq" and "text", as JSON keys, so when it's unmarshaled to a Map they are also preserved as map keys. To have them handled you need to invoke the MapSeq XML encoder as 'xml, err := mxj.MapSeq(mv).XmlIndent("", " ")'.
I'll need to find some time to trace through the CastValuesToBool(...) handling between decoders and encoders for Map and MapSeq as there is some inconsistency including the JSON decoding that uses stdlib. Don't know when that'll be right now.
If you can email me a general outline of what you're trying to accomplish, I might be able to suggest a workaround. Otherwise I'll have to recommend you investigate some other XML decoder library.