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

Hi Colin. I already answered to that question. It is a big no ! :slight_smile:
For the moment, it is just about Node-Red and what is possible to realise with.

Of course, as you helped me, I also learned a lot with you. I think I understood the main part of Node-Red but I'm not not experienced at all in javaScript.

Great, to give you a head start you can use the switch node to split for the two different flags.

Or if you want to learn more javascript try googling for ā€œif javascriptā€
Apart from that itā€™s the same as before convert it into a javascript object. You now know how to manipulate javascript objects and arrays and know where there are tutorials if you get stuck.

Good luck!

Thanks. But still need help here :slight_smile:

Hi again - where are you stuck?

When @ukmoose suggested "use the switch node to split for the two different flags" he was referring to " To be clearer, I have a function node with flag = A or flag = V"

So add a switch node & use output 1 for when the flag is A and output 2 when its V.

Then use the example I posted to generate the JS object with desired properties set then generated the XML from that.

To get you started, see below...

And heres the flow...
[{"id":"66ef025a.d32d0c","type":"tab","label":"JS-XML","disabled":false,"info":""},{"id":"335f27df.216008","type":"inject","z":"66ef025a.d32d0c","name":"Sample V XML","topic":"","payload":"<LocationRQ xmlns=\"http://skyhookwireless.com/wps/2005\" version=\"2.26\" street-address-lookup=\"full\"> <authentication version=\"2.2\"> <key key=\"KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK\" \t username=\"ABABABABABABABABABABBBA\"/> </authentication> <gps-location> </gps-location> <gsm-tower> </gsm-tower> </LocationRQ>","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":80,"wires":[["a789d227.4fbfe"]]},{"id":"a789d227.4fbfe","type":"xml","z":"66ef025a.d32d0c","name":"","property":"payload","attr":"","chr":"","x":290,"y":80,"wires":[["eb46fbb9.426138","af138338.135c3"]]},{"id":"eb46fbb9.426138","type":"debug","z":"66ef025a.d32d0c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":510,"y":80,"wires":[]},{"id":"f0de657a.034d08","type":"function","z":"66ef025a.d32d0c","name":"Get flag and other parts","func":"\n// 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# \n\nmsg.elements = msg.payload.replace('#','').split(\",\"); // this gives an array containing the bits\n// elements[0] is the long string starting IWAP01\nmsg.command = msg.elements[0].substr(0,6)\nmsg.dateStr = msg.elements[0].substr(6,6) // eg \"190215\" 15th Feb 2019\nmsg.date = new Date(Number(msg.dateStr.substr(0,2))+2000, Number(msg.dateStr.substr(2,2))-1, msg.dateStr.substr(4,2)) // 080524 - date\nmsg.flag = (msg.elements[0].substr(12,1)) // true or false - A or V\n\nreturn msg","outputs":1,"noerr":0,"x":350,"y":220,"wires":[["598b477f.dd8e18","e37c3349.9d11f"]]},{"id":"1571eb01.038e45","type":"inject","z":"66ef025a.d32d0c","name":"A Msg","topic":"","payload":"IWAP01080524A2232.9806N11404.9355E000.1061830323.8706000908000102,460,0,9520,3671#","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":220,"wires":[["f0de657a.034d08"]]},{"id":"598b477f.dd8e18","type":"debug","z":"66ef025a.d32d0c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":550,"y":220,"wires":[]},{"id":"1758ade0.5528d2","type":"comment","z":"66ef025a.d32d0c","name":"1st, determine correct JSON from example XML - this can be deleted after A/V type msg JSON format is determined","info":"","x":430,"y":40,"wires":[]},{"id":"1397aee6.d68481","type":"xml","z":"66ef025a.d32d0c","name":"","property":"payload","attr":"","chr":"","x":570,"y":400,"wires":[["6200ccb6.d2a374"]]},{"id":"6200ccb6.d2a374","type":"debug","z":"66ef025a.d32d0c","name":"Final XML","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":700,"y":400,"wires":[]},{"id":"af138338.135c3","type":"xml","z":"66ef025a.d32d0c","name":"","property":"payload","attr":"","chr":"","x":370,"y":120,"wires":[["e883506d.d6ab"]]},{"id":"e883506d.d6ab","type":"debug","z":"66ef025a.d32d0c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":490,"y":120,"wires":[]},{"id":"9796fa1a.e27e28","type":"comment","z":"66ef025a.d32d0c","name":"Now using correct JS object from above example XML, add properties and values as desired","info":"","x":360,"y":180,"wires":[]},{"id":"5357f5af.18930c","type":"comment","z":"66ef025a.d32d0c","name":"JS object from sample XML","info":"","x":760,"y":80,"wires":[]},{"id":"bd840e85.06542","type":"comment","z":"66ef025a.d32d0c","name":"Check JS converts back to usable XML","info":"","x":790,"y":120,"wires":[]},{"id":"b57b2325.41d5f","type":"comment","z":"66ef025a.d32d0c","name":"A/V msg broken down to get flag, date, etc","info":"","x":800,"y":220,"wires":[]},{"id":"ded8fdd5.17fbe","type":"comment","z":"66ef025a.d32d0c","name":"JS object to XML","info":"","x":880,"y":400,"wires":[]},{"id":"e37c3349.9d11f","type":"switch","z":"66ef025a.d32d0c","name":"Route A/V","property":"flag","propertyType":"msg","rules":[{"t":"eq","v":"A","vt":"str"},{"t":"eq","v":"V","vt":"str"}],"checkall":"true","repair":true,"outputs":2,"x":130,"y":360,"wires":[["46de7482.ae8e9c"],["93a40f32.61689"]]},{"id":"46de7482.ae8e9c","type":"function","z":"66ef025a.d32d0c","name":"Prepare msg type A","func":"//Prepare JS object and fill out fields before conversion to XML\nvar LocationRQ = {\"$\":{\"xmlns\":\"http://skyhookwireless.com/wps/2005\",\"version\":\"2.26\",\"street-address-lookup\":\"full\"},\"authentication\":[{\"$\":{\"version\":\"2.2\"},\"key\":[{\"$\":{\"key\":\"KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK\",\"username\":\"ABABABABABABABABABABBBA\"}}]}],\"gps-location\":[],\"gsm-tower\":[]}\n\n\n// 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 elements = msg.elements; \nLocationRQ.command = msg.command;\nLocationRQ.date = msg.data;\nLocationRQ.flag = msg.flag; // true or false - A or V\n\n// Get GPS datas\nlet gpsLoc = {};\nlet degreesN = Number(elements[0].substr(13,2));\nlet minutesN = Number(elements[0].substr(15,7));\nlet ns = elements[0].substr(22,1); // N or S\nlet degreesE = Number(elements[0].substr(23,3));\nlet minutesE = Number(elements[0].substr(26,7));\nlet ew = elements[0].substr(33,1); // E or W\ngpsLoc.latitude = degreesN + minutesN/60; // 2232.9806N\nif (ns === \"S\") LocationRQ.latitude = -LocationRQ.latitude;\ngpsLoc.longitude = degreesE + minutesE/60;\nif (ew === \"W\") LocationRQ.longitude = -LocationRQ.longitude; //11404.9355E\ngpsLoc.speed = elements[0].substr(34,5); // 000.1\ngpsLoc.bearing = elements[0].substr(45,6); // 323.87\ngpsLoc.constellation = {};\ngpsLoc.constellation.nsat = elements[0].substr(54,3) \n\nLocationRQ[\"gps-location\"] = [gpsLoc];\n\n\n// Get LBS datas\nlet e;\nlet gsmTower = {};\ngsmTower.mcc = elements[1];\ngsmTower.mnc = elements[2];\ngsmTower.lac = elements[3]; \ngsmTower.ci = elements[4] ;\nLocationRQ[\"gsm-tower\"] = [gsmTower];\n\nLocationRQ.signalStrength = elements[0].substr(51,3); // 060\nLocationRQ.batteryLevel = elements[0].substr(57,3); // 080\n\n\n\nmsg.payload = {LocationRQ: LocationRQ};\nreturn msg;","outputs":1,"noerr":0,"x":340,"y":320,"wires":[["1397aee6.d68481","4192613b.15701"]]},{"id":"93a40f32.61689","type":"function","z":"66ef025a.d32d0c","name":"Prepare msg type V","func":"//Prepare JS object and fill out fields before conversion to XML\nvar 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\"}}]}],\"access-point\":[{\"mac\":[\"E01C413B9414\"],\"ssid\":[\"SkyFi-Corp\"],\"signal-strength\":[\"-66\"]},{\"mac\":[\"E01C413BD528\"],\"ssid\":[\"SkyFi-Corp\"],\"signal-strength\":[\"-63\"]},{\"mac\":[\"E01C413BD514\"],\"ssid\":[\"SkyFi-Corp\"],\"signal-strength\":[\"-68\"]}]}\n\n\n// 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 elements = msg.elements; \nLocationRQ.command = msg.command;\nLocationRQ.date = msg.data;\nLocationRQ.flag = msg.flag; // true or false - A or V\n\n\n\n// Get LBS datas\nlet e;\nlet gsmTower = {};\ngsmTower.mcc = elements[1] // 460\ngsmTower.mnc = elements[2] // 0\ngsmTower.lac = elements[3] // 9520 \ngsmTower.ci = elements[4] // 3671\nLocationRQ[\"gsm-tower\"] = [gsmTower];\n\nLocationRQ.signalStrength = elements[0].substr(51,3) // 060\nLocationRQ.batteryLevel = elements[0].substr(57,3) // 080\n\n// Get WIFI datas when flag = V\nlet i;\n\nlet wifiAccessPointsStrings = elements[5].split(\"&\")\nlet j;\nlet ap = [];\nfor (j = 0; j < wifiAccessPointsStrings.length; j++) {\n let baseElements = wifiAccessPointsStrings[j].split(\"|\")\n ap.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\nLocationRQ.baseCountwifiAccessPoints = ap.length\nLocationRQ[\"access-point\"] = ap;\n\nmsg.payload = {LocationRQ: LocationRQ};\nreturn msg","outputs":1,"noerr":0,"x":340,"y":400,"wires":[["1397aee6.d68481","4192613b.15701"]]},{"id":"11bab401.4a5c0c","type":"inject","z":"66ef025a.d32d0c","name":"V Msg","topic":"","payload":"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#","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":260,"wires":[["f0de657a.034d08"]]},{"id":"7ead7fd2.4c747","type":"inject","z":"66ef025a.d32d0c","name":"Sample A XML","topic":"","payload":"<LocationRQ xmlns=\"http://skyhookwireless.com/wps/2005\" version=\"2.26\" street-address-lookup=\"full\"> <authentication version=\"2.2\"> <key key=\"YOUR API KEY HERE\" \t 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>","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":120,"wires":[["a789d227.4fbfe"]]},{"id":"4192613b.15701","type":"debug","z":"66ef025a.d32d0c","name":"Debug JS Obj","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":600,"y":320,"wires":[]},{"id":"2b00440a.d4e5ac","type":"comment","z":"66ef025a.d32d0c","name":"JS object before XML","info":"","x":820,"y":320,"wires":[]}]

1 Like

Hi,
I think there is a misunderstanding... adding a switch node when flag is A / V was done 3 weeks ago but thanks for your great job...
After your message about reverse engineering yesterday, I've also rewrited my function Node to correspond to the XML... like this :

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

let a;
answer.LocationRQ = {}                                                  // payload.LocationRQ
     // Get GPS datas when flag = A
     let h;
     answer.LocationRQ["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.LocationRQ["gps-location"][0].latitude = degreesN + minutesN/60        // 2232.9806N
        if (ns === "S") answer.latitude = -answer.latitude
        answer.LocationRQ["gps-location"][0].longitude = degreesE + minutesE/60
        if (ew === "W") answer.longitude = -answer.longitude               //11404.9355E
}
        answer.LocationRQ["gps-location"][0].speed = elements[0].substr(34,5)          // 000.1
        answer.LocationRQ["gps-location"][0].bearing = elements[0].substr(45,6)        // 323.87
        answer.LocationRQ["gps-location"][0].constellation = {}
            answer.LocationRQ["gps-location"][0].constellation.nsat = elements[0].substr(54,3)
            
     // Get LBS datas when flag = A or flag = V
     let e;
     answer.LocationRQ["gsm-tower"] = [{}];
           answer.LocationRQ["gsm-tower"][0].mcc = elements[1]                               // 460
           answer.LocationRQ["gsm-tower"][0].mnc = elements[2]                               // 0
           answer.LocationRQ["gsm-tower"][0].lac = elements[3]                               // 9520       
           answer.LocationRQ["gsm-tower"][0].ci = elements[4]                                // 3671

answer.GSMsignalStrength = elements[0].substr(51,3)                           // 060
answer.GPSbatteryLevel = elements[0].substr(57,3)                             // 080
     
     // Get WIFI datas when flag = V
     let c;
     answer.LocationRQ["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.LocationRQ["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.LocationRQ["access-point"].length
} 
        
msg.payload = answer
return msg

There are many ways to skin a cat.

If what you have works - then all is good.

I spoke too fast Steve, my code is still incomplete because I don't understand how make the correct httprequest.

On the other side, you include everything in the function nodes Prepare msg typeA/V, but there is no API connexion possible because I don't need how and where to setup the POST request...

var LocationRQ = {"$":{"xmlns":"http://skyhookwireless.com/wps/2005","version":"2.26","street-address-lookup":"full"},"authentication":[{"$":{"version":"2.2"},"key":[{"$":{"key":"KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK","username":"ABABABABABABABABABABBBA"}}]}],"gps-location":[],"gsm-tower":[]}

If I'm using the classic http request node I have to select POST and setup http://skyhookwireless.com/wps/2005 as URL or I have to set it up as -set by msg.method- but here I have to write the necessary infos before in a function node...

the cookbook part of the website might help you. there are lots of http examples

Thanks ukmoose... but I don't have any problem to connect an API with httprequest node ... in JSON. In XML, it is another story!!

If you are trying to change the http headers, it needs to be down as part of the msg object that is sent to the http request node.

If you want to know what to send the xml node to covert to that, use the xml node to convert the message object TO xml

I undestood this... but the message does not want to hear about... :slight_smile:

My error is here in the node to prepare the httprequest where I wrote :

msg.headers = {};
msg.headers['content-type'] = 'application/xml';
return msg;

instead of : msg.headers['content-type'] = 'text/xml';

Hi Steve. Do you have 2 mns to help me to split a command, exactly the way you did it the other day.
I solved my problem for xml... but the split is not done correctly here.

https://discourse.nodered.org/t/cant-split-to-prepare-xml/8706

Thanks if you can!!

Please donā€™t post the same question in multiple places

I just made a link to the new request. And this not the same present message to split... :wink: