Ist it possible to (and if yes how can I) directly import the content of 1 array / object in a XML?

Hi,
I succeed to format my json objects in XML to make a API request, but I can't get directly their value ...
Below, I'm just importing the name of the array... and not the content of them? Does someone knows how to do this ?

The original values are :

gps-location: array[1]
0: object 
         latitude: 22.549676666666667
         longitude: 114.08225833333333
         speed: "000.1"
         bearing: "323.87"
         constellation: object
            nsat: "009"

gsm-tower: array[1]
0: object
        mcc: "226"
        mnc: "10"
        lac: "1440"
        ci: "22327"

and I just get gps-location and gsm-tower in my return message...

If you dump the data to the debug node, you will be able to copy the right path straight from the output.

Thanks.

Of course this is the first thing I did :slightly_smiling_face:
This is just available to insert json objects/array in js sript...

XML does not stand json... If I insert a json object as "msg.payload.flag" in the XML code... It will just display "msg.payload.flag"... and not the content...

Hi, without screen shots I am unable to understand exactly what you are trying to achieve.
However, have you tried passing the object from the array to an XML node?

E.g. use a change node to set msg.payload with the value of object[0] then pass that to an XML node.
Might get you a step closer to what you're trying to achieve.

OK ... just 1 mn to convert ...What I want to do is to pick up some datas from a function node and to convert them in XML to make a http request to an API.

I'm on mobile and can't import your flow. Screenshots with annotations might help me understand your issue otherwise I'm guessing & cant be any real help.

I need to load : answer["gsm-tower"] array and answer["gps-location"] in my XML function node...

function node is :

// flag = A
//IWAP01080524A2232.9806N11404.9355E000.1061830323.8706000908000102,460,0,9520,3671#
// flag = V
//IWAP01080524V0000.0000N00000.0000E000.1061830323.8706000908000102,460,0,9520,3671,Home|74-DE-2B-44-88-8C|97&Home1|74-DE-2B-44-88-8C|97&Home2|74-DE-2B-44-88-8C|97&Home3|74-DE-2B-44-88-8C|97# 
let answer = {}
let elements = msg.payload.replace('#','').split(",")                                                           // this gives an array containing the bits
// elements[0] is the long string starting IWAP01
answer.command = elements[0].substr(0,6)
let dateStr = elements[0].substr(6,6)                                                                           // eg "190215" 15th Feb 2019
answer.date = new Date(Number(dateStr.substr(0,2))+2000, Number(dateStr.substr(2,2))-1, dateStr.substr(4,2))    // 080524 - date
answer.flag = (elements[0].substr(12,1))                                                                        // true or false - A or V
// Get GPS datas
let c;
answer["gps-location"] = [{}]
    if (answer.flag === "A") {
        let degreesN = Number(elements[0].substr(13,2))
        let minutesN = Number(elements[0].substr(15,7))
        let ns = elements[0].substr(22,1)                                  // N or S
        let degreesE = Number(elements[0].substr(23,3))
        let minutesE = Number(elements[0].substr(26,7))
        let ew = elements[0].substr(33,1)                                  // E or W
        answer["gps-location"][0].latitude = degreesN + minutesN/60        // 2232.9806N
        if (ns === "S") answer.latitude = -answer.latitude
        answer["gps-location"][0].longitude = degreesE + minutesE/60
        if (ew === "W") answer.longitude = -answer.longitude               //11404.9355E
}
        answer["gps-location"][0].speed = elements[0].substr(34,5)          // 000.1
        answer["gps-location"][0].bearing = elements[0].substr(45,6)        // 323.87
        answer["gps-location"][0].constellation = {}
            answer["gps-location"][0].constellation.nsat = elements[0].substr(54,3)    

// Get LBS datas
let e;
answer["gsm-tower"] = [{}];
    answer["gsm-tower"][0].mcc = elements[1]                               // 460
    answer["gsm-tower"][0].mnc = elements[2]                               // 0
    answer["gsm-tower"][0].lac = elements[3]                               // 9520       
    answer["gsm-tower"][0].ci = elements[4]                                // 3671

answer.signalStrength = elements[0].substr(51,3)                           // 060
answer.batteryLevel = elements[0].substr(57,3)                             // 080

// Get WIFI datas when flag = V
let i;
answer["access-point"] = [];
    if (answer.flag === "V") {
        let wifiAccessPointsStrings = elements[5].split("&")
        let j;
        for (j = 0; j < wifiAccessPointsStrings.length; j++) {
            let baseElements = wifiAccessPointsStrings[j].split("|")
            answer["access-point"].push({ ssid: baseElements[0], mac: baseElements[1], ["signal-strength"]: baseElements[2] })  // Home|74-DE-2B-44-88-8C|97&Home1|74-DE-2B-44-88-8C|97&Home2|74-DE-2B-44-88-8C|97&Home3|74-DE-2B-44-88-8C|97
    }
    // adjust baseCountwifiAccessPoints just in case the number actually there didn't match that expexted
    answer.baseCountwifiAccessPoints = answer["access-point"].length
}

msg.payload = answer
return msg

and XML where to load function node datas is :

<LocationRQ xmlns="http://skyhookwireless.com/wps/2005"
            version="2.26"
            street-address-lookup="full">
<authentication version="2.2">
<key key="KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK"
	 username="ABABABABABABABABABABABABABAB"/>
</authentication>
              <gps-location>            
               **msg.... answer["gps-location"]**                       
              </gps-location>
              <gsm-tower>
              **msg.... answer["gsm-tower"]**                   
              </gsm-tower>
</LocationRQ>

Am I right that you started with a javascript object and converted to XML, and now you are trying to modify the XML? Much better I think then to do it all with the js object and convert to XML when it is all complete.

Ok so I've had to do something similar before and the only way I could figure it out was to work in reverse.

  1. Use a complete, working XML sample, pasted into an inject node.
  2. Pass that to an XML node then to another XML node then to a debug node.

This will give you the final JSON object. If you pass this to another XML node it should convert to correct format you desire.

So then use the JSON output to debug as a clue as to how to format your data before conversation to XML.

Basically, work backwards from good XML sample data to a JSON object as an example of how to build your data in the function node in the correct format ready to send to XML node.

Hi Colin!
Nice to see you back :wink:

Here is what I did also in your idea... but not working better !

[{"id":"e1fe9f07.bf544","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"583fc13d.de8e3","type":"template","z":"e1fe9f07.bf544","name":"","field":"payload","fieldType":"msg","format":"text","syntax":"plain","template":"<LocationRQ xmlns=\"http://skyhookwireless.com/wps/2005\"\n            version=\"2.26\"\n            street-address-lookup=\"full\">\n<authentication version=\"2.2\">\n<key key=\"KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK\"\n\t username=\"ABABABABABABABABABABBBA\"/>\n</authentication>\n              <gps-location>\n                        \n              </gps-location>\n              <gsm-tower>\n\n              </gsm-tower>\n</LocationRQ>","output":"str","x":378.6999740600586,"y":211.00000095367432,"wires":[["89e48660.c124c8","15378136.073abf"]]},{"id":"89e48660.c124c8","type":"xml","z":"e1fe9f07.bf544","name":"","property":"payload","attr":"","chr":"","x":369.69998931884766,"y":254.99999713897705,"wires":[["5cdb24a0.06d03c"]]},{"id":"65d79b0.064ef64","type":"debug","z":"e1fe9f07.bf544","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":180,"y":261.8000011444092,"wires":[]},{"id":"15378136.073abf","type":"debug","z":"e1fe9f07.bf544","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":579.0000114440918,"y":211.79999446868896,"wires":[]},{"id":"5cdb24a0.06d03c","type":"debug","z":"e1fe9f07.bf544","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":577.0000114440918,"y":254.79999446868896,"wires":[]},{"id":"8d839b89.50b1e8","type":"function","z":"e1fe9f07.bf544","name":"AP01 split flag A/V","func":"// flag = A\n//IWAP01080524A2232.9806N11404.9355E000.1061830323.8706000908000102,460,0,9520,3671#\n// flag = V\n//IWAP01080524V0000.0000N00000.0000E000.1061830323.8706000908000102,460,0,9520,3671,Home|74-DE-2B-44-88-8C|97&Home1|74-DE-2B-44-88-8C|97&Home2|74-DE-2B-44-88-8C|97&Home3|74-DE-2B-44-88-8C|97# \nlet answer = {}\nlet elements = msg.payload.replace('#','').split(\",\")                                                           // this gives an array containing the bits\n// elements[0] is the long string starting IWAP01\nanswer.command = elements[0].substr(0,6)\nlet dateStr = elements[0].substr(6,6)                                                                           // eg \"190215\" 15th Feb 2019\nanswer.date = new Date(Number(dateStr.substr(0,2))+2000, Number(dateStr.substr(2,2))-1, dateStr.substr(4,2))    // 080524 - date\nanswer.flag = (elements[0].substr(12,1))                                                                        // true or false - A or V\n// Get GPS datas\nlet c;\nanswer[\"gps-location\"] = [{}]\n    if (answer.flag === \"A\") {\n        let degreesN = Number(elements[0].substr(13,2))\n        let minutesN = Number(elements[0].substr(15,7))\n        let ns = elements[0].substr(22,1)                                  // N or S\n        let degreesE = Number(elements[0].substr(23,3))\n        let minutesE = Number(elements[0].substr(26,7))\n        let ew = elements[0].substr(33,1)                                  // E or W\n        answer[\"gps-location\"][0].latitude = degreesN + minutesN/60        // 2232.9806N\n        if (ns === \"S\") answer.latitude = -answer.latitude\n        answer[\"gps-location\"][0].longitude = degreesE + minutesE/60\n        if (ew === \"W\") answer.longitude = -answer.longitude               //11404.9355E\n}\n        answer[\"gps-location\"][0].speed = elements[0].substr(34,5)          // 000.1\n        answer[\"gps-location\"][0].bearing = elements[0].substr(45,6)        // 323.87\n        answer[\"gps-location\"][0].constellation = {}\n            answer[\"gps-location\"][0].constellation.nsat = elements[0].substr(54,3)    \n\n// Get LBS datas\nlet e;\nanswer[\"gsm-tower\"] = [{}];\n    answer[\"gsm-tower\"][0].mcc = elements[1]                               // 460\n    answer[\"gsm-tower\"][0].mnc = elements[2]                               // 0\n    answer[\"gsm-tower\"][0].lac = elements[3]                               // 9520       \n    answer[\"gsm-tower\"][0].ci = elements[4]                                // 3671\n\nanswer.signalStrength = elements[0].substr(51,3)                           // 060\nanswer.batteryLevel = elements[0].substr(57,3)                             // 080\n\n// Get WIFI datas when flag = V\nlet i;\nanswer[\"access-point\"] = [];\n    if (answer.flag === \"V\") {\n        let wifiAccessPointsStrings = elements[5].split(\"&\")\n        let j;\n        for (j = 0; j < wifiAccessPointsStrings.length; j++) {\n            let baseElements = wifiAccessPointsStrings[j].split(\"|\")\n            answer[\"access-point\"].push({ ssid: baseElements[0], mac: baseElements[1], [\"signal-strength\"]: baseElements[2] })  // Home|74-DE-2B-44-88-8C|97&Home1|74-DE-2B-44-88-8C|97&Home2|74-DE-2B-44-88-8C|97&Home3|74-DE-2B-44-88-8C|97\n    }\n    // adjust baseCountwifiAccessPoints just in case the number actually there didn't match that expexted\n    answer.baseCountwifiAccessPoints = answer[\"access-point\"].length\n}\n\nmsg.payload = answer\nreturn msg","outputs":1,"noerr":0,"x":183.69994735717773,"y":163,"wires":[["8100db3.89a4428"]]},{"id":"8100db3.89a4428","type":"switch","z":"e1fe9f07.bf544","name":"Route A/V","property":"payload.flag","propertyType":"msg","rules":[{"t":"eq","v":"A","vt":"str"},{"t":"eq","v":"V","vt":"str"}],"checkall":"true","repair":true,"outputs":2,"x":191.6999740600586,"y":215.19997787475586,"wires":[["66ad29c7.174d38","65d79b0.064ef64"],[]]},{"id":"66ad29c7.174d38","type":"function","z":"e1fe9f07.bf544","name":"MLS LBS+WIFI","func":"// Get positions from wifiAccessPoints\n\nvar data =\n{\n    [\"gps-location\"] : msg.payload[\"gps-location\"],\n   \n    [\"gsm-tower\"] : msg.payload[\"gsm-tower\"],\n}\nvar msg = {\n    \"headers\" : {\n        \"Content-Type\": \"application/json\",\n    },\n};\nreturn msg;\n","outputs":1,"noerr":0,"x":387.6999740600586,"y":155.00000095367432,"wires":[["583fc13d.de8e3","11f91fd7.7db3f"]]},{"id":"9c139de5.c10a","type":"inject","z":"e1fe9f07.bf544","name":"Valid IWAP01","topic":"","payload":"IWAP01190215A2232.9806N11404.9355E000.1061830323.8706000908000102,226,10,1440,22327#","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":96.69994354248047,"y":67.00000190734863,"wires":[["8d839b89.50b1e8"]]},{"id":"11f91fd7.7db3f","type":"debug","z":"e1fe9f07.bf544","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":604.9999542236328,"y":154.20000076293945,"wires":[]}]

Thanks Steve-Mcl... but "do this" and "do that" does not help me to solve this problem as I'm on 48h on the same problem ... unfortunatly!! There are too much possibilities and issues relative to these possibilities.

@jycemea I can't help directly at the moment, only offer advice.

Trust me doing this in reverse is quite simple and takes out the guess work.

Send working data to XML node. See how it converts to JS object.

Based on what the resulting JS object looks like, generate code to build an identical JS object yourself then it WILL convert to the XML you need.

Do you follow me? Does it make sense?

I suppose until you try to reverse engineer you won't see how simple this can be.

Give it a try.

I may be on line in a couple of hours so give it a go. If you get stuck, post a complete working XML sample data and I'll reverse it for you.

Steve, all the examples I've found (include here, at https://cookbook.nodered.org/basic/convert-xml) are never calling any API...

My problem is not to sctructure the files, but just to transfer a json content from a function node to a xml file already formatted by the editor of the API..;

To transfer JSON content to XML file, you need to convert JSON to XML.
You also need the is object in the correct format first to get the correct XML structure. That's why I said use good XML sample data, conversation that to XML and see what the is object looks like.

Like I said earlier, I can only offer advice without annotated screen shots of your flow.

If you post what your final valid XML should look like I'll give it try later.

ok, so without a valid XML final sample data I have made some assumptions.

The output may not be exactly as you required but hopefully it will put you on the right path.

This is what I tried to explain in words above...

This is the output...

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<LocationRQ
    xmlns="http://skyhookwireless.com/wps/2005" version="2.26" street-address-lookup="full">
    <authentication version="2.2">
        <key key="KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK" username="ABABABABABABABABABABBBA"/>
    </authentication>
    <gps-location>
        <latitude>22.549676666666667</latitude>
        <longitude>114.08225833333333</longitude>
        <speed>000.1</speed>
        <bearing>323.87</bearing>
        <constellation>
            <nsat>009</nsat>
        </constellation>
    </gps-location>
    <gsm-tower>
        <mcc>226</mcc>
        <mnc>10</mnc>
        <lac>1440</lac>
        <ci>22327</ci>
    </gsm-tower>
    <command>IWAP01</command>
    <date/>
    <flag>A</flag>
    <signalStrength>060</signalStrength>
    <batteryLevel>080</batteryLevel>
</LocationRQ>

NOTES:

  • There is likely more properties in the object than your original template - these can be deleted (or never added) before you send to XML node.
  • Without sample XML data I cannot tell if the gsm-tower entry should be elements or attributes
  • Without sample XML data I cannot tell if the gps-location entry should be elements or attributes

Thanks for your time. I'm going to try and will soon mark this as "solved"... I hope!! :smile:

It is complicate to give you the correct example. What I'm doing is to mix possibilities as described here, at http://resources.skyhookwireless.com/wiki/type/documentation/precision-location/location-api-v226/195167055

To be clearer, I have a function node with flag = A or flag = V

When flag = A I need to collect datas relative to GPS (gps-location) and datas relative to GSM (gsm-tower) and to send a request to the XML API

When flag = V I need to collect datas relative to WIFI (access-point) and datas relative to GSM (gsm-tower) and to send a request to the XML API

Look, here is one XML example extraxted from the doc :

Example API :

<LocationRQ xmlns="http://skyhookwireless.com/wps/2005"
            version="2.26"
            street-address-lookup="full">
<authentication version="2.2">
<key key="YOUR API KEY HERE"
	 username="DEVICE SERIAL NUM, MAC ADDRESS, OR OTHER UNIQUE ID HERE"/>
</authentication>
              <access-point>
                            <mac>E01C413B9414</mac>
                            <ssid>SkyFi-Corp</ssid>
                            <signal-strength>-66</signal-strength>
              </access-point>
              <access-point>
                            <mac>E01C413BD528</mac>
                            <ssid>SkyFi-Corp</ssid>
                            <signal-strength>-63</signal-strength>
              </access-point>
              <access-point>
                            <mac>E01C413BD514</mac>
                            <ssid>SkyFi-Corp</ssid>
                            <signal-strength>-68</signal-strength>
              </access-point>
</LocationRQ>

So now you are skilled at Javascript Objects and Arrays, what have you tried?

@jycemea as a matter of interest, are you doing all this for your personal use or are you hoping for commercial gain?

ukmoose, I'm going to finish today with this part today.