Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the JavaScript library or module that can update json based on jsonpath?

I've used some Java library to achieve this before. I thought since json is more intrinsic to JavaScript to Java, it should be quite easy to find a library that does that. But surprisingly no.

An example of what I look for is: given a Json object:

 {
  "store": {
    "book": [
      {
        "category": "reference",
        "author": "Nigel Rees",
        "title": "Sayings of the Century",
        "price": 8.95
      },
      {
        "category": "fiction",
        "author": "Evelyn Waugh",
        "title": "Sword of Honour",
        "price": 12.99
      },
      {
        "category": "fiction",
        "author": "Herman Melville",
        "title": "Moby Dick",
        "isbn": "0-553-21311-3",
        "price": 8.99
      },
      {
        "category": "fiction",
        "author": "J. R. R. Tolkien",
        "title": "The Lord of the Rings",
        "isbn": "0-395-19395-8",
        "price": 22.99
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 19.95
    }
  }
}

and a Jsonpath like:

 '$..author'

I can call a JavaScript function that takes JsonObject, JsonPath and newValue (Shakespeare) as the input parameters, and change the value of all occurrences of the JSONPATH to a new value, e.g. to

 {
  "store": {
    "book": [
      {
        "category": "reference",
        "author": "Shakespeare",
        "title": "Sayings of the Century",
        "price": 8.95
      },
      {
        "category": "fiction",
        "author": "Shakespeare",
        "title": "Sword of Honour",
        "price": 12.99
      },
      {
        "category": "fiction",
        "author": "Shakespeare",
        "title": "Moby Dick",
        "isbn": "0-553-21311-3",
        "price": 8.99
      },
      {
        "category": "fiction",
        "author": "Shakespeare",
        "title": "The Lord of the Rings",
        "isbn": "0-395-19395-8",
        "price": 22.99
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 19.95
    }
  }
}

Any suggestions?

like image 973
user1559625 Avatar asked Jan 21 '26 13:01

user1559625


1 Answers

Try to use jsonpath npm package.

use apply method to change values of a JSON object and returns nodes. You'll need to add some method that will change the value according to the path from each node.

const _ = require('lodash');
var jp = require('jsonpath');
const data = {
"store": {
  "book": [ 
    {
      "category": "reference",
      "author": "Nigel Rees",
      "title": "Sayings of the Century",
      "price": 8.95
    }, {
      "category": "fiction",
      "author": "Evelyn Waugh",
      "title": "Sword of Honour",
      "price": 12.99
    }, {
      "category": "fiction",
      "author": "Herman Melville",
      "title": "Moby Dick",
      "isbn": "0-553-21311-3",
      "price": 8.99
    }, {
       "category": "fiction",
      "author": "J. R. R. Tolkien",
      "title": "The Lord of the Rings",
      "isbn": "0-395-19395-8",
      "price": 22.99
    }
  ],
  "bicycle": {
    "color": "red",
    "price": 19.95
  }
}
  }
    var nodes = jp.apply(data, '$..author', function(value) { return value.toUpperCase() });
    // [
    //   { path: ['$', 'store', 'book', 0], value: 'NIGEL REES' },
    //   { path: ['$', 'store', 'book', 1], value: 'EVELYN WAUGH' },
    //   { path: ['$', 'store', 'book', 2], value: 'HERMAN MELVILLE' },
    //   { path: ['$', 'store', 'book', 3], value: 'J. R. R. TOLKIEN' }
    // ]

    function chnageValueByPath(object, path, value) {
       if(Array.isArray(path) && path[0] === '$') {
            const pathWithoutFirstElement = path.slice(1);
            _.set(object, pathWithoutFirstElement, value);
       }
    }

    function changeValuesByPath(object, nodes, lastPropertyName) {
        nodes.forEach((node)=> {
            chnageValueByPath(object, node.path.concat(lastPropertyName), node.value);
        })

        return object;
    }

    const result = changeValuesByPath(data, nodes, 'author');
    console.log(result);
like image 111
Igor Litvinovich Avatar answered Jan 23 '26 02:01

Igor Litvinovich



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!