# Trouble reading from JSObject created from XML

**URL:** <https://discourse.nodered.org/t/trouble-reading-from-jsobject-created-from-xml/75947>\
**Category:** General\
**Created:** [1 March 2023 15:36 UTC](https://discourse.nodered.org/t/trouble-reading-from-jsobject-created-from-xml/75947 "2023-03-01T15:36:43Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Darren](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/darren/32/92202_2.png) [@Darren](https://discourse.nodered.org/u/Darren)\
**Post date:** [1 March 2023 15:36 UTC](https://discourse.nodered.org/t/trouble-reading-from-jsobject-created-from-xml/75947/1 "2023-03-01T15:36:43Z")

</div>

I'm trying to use a flow to process an XML generated by GXWorks3 for industrial PLCs into some sort of array for use in more complex flows. I've puzzled over it for a couple days, tried ChatGPT, and finally turn to the forum in hopes of help.

## flow:

[Flow XML to JSON - Pastebin.com](https://pastebin.com/Xd1yAPhd)

Input is a massive XML with a lot of extra nonsense, we chop it down to the bit we need, then operate on that using a function that should output a JSON (or JSObject, I'm not sure, not a JS developer), similar to this format: [Desired output format - Pastebin.com](https://pastebin.com/kZ31AQez).

After much experimentation, I'm trying:

```auto
var arr = msg.payload; // get the array
var rv = {};// create a new empty object

for (var i = 0; i < arr.length; ++i) {
    let key = msg.payload[i].variable[i].$.name;
    rv[key] = {
        address: msg.payload[i].variable[i].$.address, 
        array_data_type_name: "", // empty
        fc: '', // empty, change sign?
        quantity: 1, // empty
        type_name: Object.keys(msg.payload[i].variable[i].type[0]), //object keys
        word_length: 1 // empty
    }; // replace arr[i] with selected pieces  
}

msg.payload = rv;
return msg;

```

based off examples from elsewhere in the forum, but it chokes at "$", (or elsewhere, if I eliminate that) with _**"TypeError: Cannot read properties of undefined (reading '$')"**_.

I've done hobby web development and programming at university, but am not a professional JS developer. Can anyone please help me solve this problem?

---

<div class="post-metadata">

**Author:** ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)\
**Post date:** [1 March 2023 17:50 UTC](https://discourse.nodered.org/t/trouble-reading-from-jsobject-created-from-xml/75947/2 "2023-03-01T17:50:15Z")

</div>

The variable array are different lengths. so your for loop works for payload but not for the variable array.  
also some variable arrays do not contain address.  
try this

```auto
let arr = msg.payload; // get the array
let rv = {};// create a new empty object
arr.forEach(obj_payload =>{
    if(obj_payload.variable){
        obj_payload.variable.forEach(obj_variable => {
            let key = obj_variable.$.name;
            if(obj_variable.$.address){
                rv[key] = {
                    address: obj_variable.$.address, 
                    array_data_type_name: "", // empty
                    fc: '', // empty, change sign?
                    quantity: 1, // empty
                    type_name: Object.keys(obj_variable.type[0]), //object keys
                    word_length: 1 // empty
                }; // replace arr[i] with selected pieces  
            }
        })
    }
});
msg.payload = rv;
return msg;

```

---

<div class="post-metadata">

**Author:** ![Darren](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/darren/32/92202_2.png) [@Darren](https://discourse.nodered.org/u/Darren)\
**Post date:** [2 March 2023 10:38 UTC](https://discourse.nodered.org/t/trouble-reading-from-jsobject-created-from-xml/75947/4 "2023-03-02T10:38:45Z")

</div>

That is awesome and works very well! I experimented with my boss until late yesterday, and we were approaching a solution, but this is beyond what we did and has solved several issues I had yet to solve (e.g. irregularly nested names). Thank you so much!

Once I've figured out how to adjust `type_name: Object.keys(obj_variable.type[0])` to return `BOOL` instead of `0: 'BOOL'`, I reckon it'll be 100% sorted. [Wondering if it is maybe impossible in JS?](https://stackoverflow.com/questions/51005183/get-name-of-an-array-or-object-by-javascript)

---

<div class="post-metadata">

**Author:** ![Darren](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/darren/32/92202_2.png) [@Darren](https://discourse.nodered.org/u/Darren)\
**Post date:** [2 March 2023 13:36 UTC](https://discourse.nodered.org/t/trouble-reading-from-jsobject-created-from-xml/75947/5 "2023-03-02T13:36:01Z")

</div>

E1cid's solution works, I only edited `type_name` to:

```auto
type_name: Object.keys(obj_variable.type[0]).toString(),

```

which will pick out BOOL, INT, etc. from the horridly formatted XML. This was based off [array to string on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toString).

My original code was inspired by [this post by Steve-Mcl](https://discourse.nodered.org/t/array-to-json-object/46261/2) (and I just noticed you chimed in with a similar fix back then, too, E1cid!)

Thank you so much!

---

<div class="post-metadata">

**Author:** ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)\
**Post date:** [2 March 2023 14:22 UTC](https://discourse.nodered.org/t/trouble-reading-from-jsobject-created-from-xml/75947/6 "2023-03-02T14:22:58Z")

</div>

> [@Darren](#):
>
> Object.keys(obj\_variable.type[0])

I thought that may be wrong and left it for you to figure out

```auto
Object.keys(obj_variable.type[0])[0]

```

should work, if only 1 item.  
Else

```auto
Object.keys(obj_variable.type[0]).join(",")

```

If it returns more than 1 then the text will be `one,two`

---

<div class="post-metadata">

**Author:** ![Darren](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/darren/32/92202_2.png) [@Darren](https://discourse.nodered.org/u/Darren)\
**Post date:** [2 March 2023 15:34 UTC](https://discourse.nodered.org/t/trouble-reading-from-jsobject-created-from-xml/75947/7 "2023-03-02T15:34:49Z")

</div>

![BOOL array](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/1/3/13708fa2d0c2b8a0ada75c8ea9ee7731d30b903a.png)  
Future readers, that's basically what it looks like, and unlike getting the values of the object fields for the rest of the XML, the `type_name` field is malformed and we use the above methods to get field name "BOOL" or "INT" etc. (array value is always empty)

Thank you so much for helping me!

---

<div class="post-metadata">

**Author:** ![Darren](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/darren/32/92202_2.png) [@Darren](https://discourse.nodered.org/u/Darren)\
**Post date:** [2 March 2023 15:40 UTC](https://discourse.nodered.org/t/trouble-reading-from-jsobject-created-from-xml/75947/8 "2023-03-02T15:40:08Z")

</div>

Would `var look_up_table = Object(msg.payload);` be enough in the next function node to get a JS object of the correctly generated object from the above? EDIT: after logging to console, yes, it appears it is.

I'm happy, the bit of the program I was working on now seems to be 100% functional.

There are some other flows and stuff connected that still have issues; not sure why, but they're in the general program, not in this section. Odd that it isn't 100% yet, as the generated data from this topic's node looks the same as one of our working installations.

---

<div class="post-metadata">

**Author:** ![Darren](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/darren/32/92202_2.png) [@Darren](https://discourse.nodered.org/u/Darren)\
**Post date:** [3 March 2023 15:40 UTC](https://discourse.nodered.org/t/trouble-reading-from-jsobject-created-from-xml/75947/9 "2023-03-03T15:40:13Z")

</div>

Turns out, there were some undocumented variables that I needed to account for that no-one informed me on. The corrected code:

```auto
let arr = msg.payload; // get the array
let rv = {}; // create a new empty object
let fc = []; 

arr.forEach(obj_payload => {
    if (obj_payload.variable) {
        obj_payload.variable.forEach(obj_variable => {
                let key = obj_variable.$.name;
                if (obj_variable.$.address) {

                    // assign function code depending on D or M (other) prefix
                    if (obj_variable.$.address.indexOf('D') > -1) {
                        fc = 1;
                    } else {
                        fc = 3;
                    }

                    // strip D/M from head of address
                    obj_variable.$.address = obj_variable.$.address.substring(1); 

                    // populate the rest of the JSObject
                    rv[key] = {
                        address: obj_variable.$.address, // addresses, trimmed of letters
                        array_data_type_name: "", // empty
                        fc: fc, // function code
                        quantity: 1, // empty
                        type_name: Object.keys(obj_variable.type[0]).toString(), //object keys
                        word_length: 1, // empty
                        unitid: 255 // previously added by lvc_labels
                    }; // replace arr[i] with selected pieces  
            }
        })
    }
});

msg.payload = rv;
return msg;

```

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [17 March 2023 15:41 UTC](https://discourse.nodered.org/t/trouble-reading-from-jsobject-created-from-xml/75947/10 "2023-03-17T15:41:01Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
