mxj icon indicating copy to clipboard operation
mxj copied to clipboard

Namespace prefixes stripped out from XML element keys and attributes

Open sunil904 opened this issue 1 year ago • 10 comments

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.

sunil904 avatar Jul 11 '24 19:07 sunil904

Can you provide example to review?

clbanning avatar Jul 11 '24 22:07 clbanning

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

sunil904 avatar Jul 12 '24 10:07 sunil904

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))

} `

clbanning avatar Jul 15 '24 16:07 clbanning

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.

sunilgandipadala avatar Jul 15 '24 16:07 sunilgandipadala

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.)

clbanning avatar Jul 15 '24 17:07 clbanning

Yes, I go the same errors with go1.21.3

sunilgandipadala avatar Jul 15 '24 18:07 sunilgandipadala

Thanks. Give me a few days to look into this.

clbanning avatar Jul 15 '24 18:07 clbanning

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.

clbanning avatar Jul 15 '24 18:07 clbanning

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

sunilgandipadala avatar Jul 22 '24 11:07 sunilgandipadala

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.

clbanning avatar Jul 23 '24 19:07 clbanning