1

So, I'm working on pulling data from the https://www.aviationweather.gov/dataserver and storing it in a mongoDB. The API returns XML, and using the xml2js module for node I can convert it fairly easily to JSON and store it in a mongodb. However, the xml2js module is not 100% perfect in it's conversion, and I would like to modify some of the output after the fact, but I am not sure where to start. I was hoping someone can give me a nudge in the right direction.

Here is the current JSON output from the xml2js conversion. I've trimmed it for just the relevant parts...let me know if you need the whole thing:

With one result, it looks like this:

"sky_condition": {
        "$": {
            "sky_cover": "OVC",
            "cloud_base_ft_agl": "1600"
        }

With multiple results, it looks like this (could be a max of 4 results):

"sky_condition": [{
        "$": {
            "sky_cover": "BKN",
            "cloud_base_ft_agl": "1800"
        }
    }, {
        "$": {
            "sky_cover": "OVC",
            "cloud_base_ft_agl": "4100"
        }
    }]

I am hopeful that there is a way that it could be made to look like this (and up to 4 possible "cloud layers":

    "sky_condition": [
    {
        "sky_cover": "OVC",
        "cloud_base_ft_agl": "1600"
    }
],

I hope this is clear, and I really appreciate any help that is tossed my way.

1
  • Answer posted below, feel free to ask any questions if I misunderstood your need. Commented Feb 7, 2019 at 18:35

2 Answers 2

1

You can iterate over the keys of the object, and push the sky conditions to an array when you see the $ key.

Say the API returns this:

let objRet = {
    someKey: "someObject",
    someOtherKey: "someOtherObject",
    "sky_condition": [{
        "$": {
            "sky_cover": "BKN",
            "cloud_base_ft_agl": "1800"
        }
    }, {
        "$": {
            "sky_cover": "OVC",
            "cloud_base_ft_agl": "4100"
        }
    }]
}

We then design a function:

function processObj(obj){
  for(let key in obj){
        if(typeof obj[key] == "object"){
            //If content of obj[key] is an object, process it
            processObj(obj[key]);
        }
    if(key == "$"){
        //If key is '$', push the contents of the key to our array of conditions
        skyConditions.push(obj[key]);
    }
  }
}

That we call like this:

let skyConditions = [];

processObj(objRet);
objRet["sky_condition"] = skyConditions;

console.log(objRet);

Will return:

{
    someKey: "someObject",
    someOtherKey: "someOtherObject",
    "sky_condition":[
        {
            "sky_cover": "BKN",
            "cloud_base_ft_agl": "1800"
        },{
            "sky_cover": "OVC",
            "cloud_base_ft_agl": "4100"
        }
    ]
}
Sign up to request clarification or add additional context in comments.

1 Comment

This got it. Thanks! I added some additional code to iterate through all of the results from the API and it's a beautiful thing. Cheers!
0

You can use xml-js instead of xml2js. It doesn't add the "$" key and returns a neat object, then you don't have to create a separate function to refactor the JSON. https://www.npmjs.com/package/xml-js

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.