能基于jsonpath更新json的JavaScript库或模块是什么?

时间:2019-02-06 10:48:08

标签: javascript node.js jsonpath

我以前使用过一些Java库来实现此目的。我认为,由于JSON是Java的JavaScript所固有的,因此找到可以做到这一点的库应该很容易。但令人惊讶的是。

我要寻找的示例是:给定一个Json对象:

 {
  "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
    }
  }
}

和类似的Jsonpath:

 '$..author'

我可以调用一个将JsonObject,JsonPath和newValue(Shakespeare)作为输入参数的JavaScript函数,并将所有出现的JSONPATH的值更改为一个新值,例如到

 {
  "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
    }
  }
}

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

尝试使用 jsonpath npm软件包。

使用 apply 方法更改JSON对象的值并返回节点。 您需要添加一些方法,该方法将根据每个节点的路径来更改值。

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);