JSON从子对象获取父对象

时间:2016-02-25 20:52:53

标签: json jsonpath

如果 brand_id =='983',我如何获得折扣值。

示例JSON:

{
     "prods": [
               {
            "info": {
                  "rate": 100
                    },
            "grocery": [
                     {
                      "brand": "A",
                      "brand_id": "983"
                     },
                     {
                      "brand": "B",
                      "brand_id": "253"
                     }
                     ],
             "discount": "20"
         }
     ]
}

我到目前为止所尝试的是

$.prods[*].grocery[?(@.brand_id=='983')]

这将返回匹配对象的列表/数组。但我无法回到树上。对此有何帮助?

2 个答案:

答案 0 :(得分:2)

事实上,JSONPath并不是很擅长,所以我用自己的小型库解决了这个问题;所以,这是你的例子的小提琴:

https://jsfiddle.net/YSharpLanguage/j9oetwnn/3

其中:

var products = {
     "prods": [
        {
            "info": {
                  "rate": 85
                    },
            "grocery": [
                     {
                      "brand": "C",
                      "brand_id": "984"
                     },
                     {
                      "brand": "D",
                      "brand_id": "254"
                     }
                     ],
             "discount": "15"
        },
        {
            "info": {
                  "rate": 100
                    },
            "grocery": [
                     {
                      "brand": "A",
                      "brand_id": "983"
                     },
                     {
                      "brand": "B",
                      "brand_id": "253"
                     }
                     ],
             "discount": "20"
         }
     ]
};

function GroceryItem(obj) {
  return (typeof obj.brand === "string") && (typeof obj.brand_id === "string");
}

    // last parameter set to "true", to grab all the "GroceryItem" instances
    // at any depth:
var itemsAndDiscounts = [ products ].nodeset(GroceryItem, true).
    map(
      function(node) {
        var item = node.value, // node.value: the current "GroceryItem" (aka "$.prods[*].grocery[*]")

            discount = node.parent. // node.parent: the array of "GroceryItem" (aka "$.prods[*].grocery")
                       parent. // node.parent.parent: the product (aka "$.prods[*]")
                       discount; // node.parent.parent.discount: the product discount

        // finally, project into an easy-to-filter form:
        return { id: item.brand_id, discount: discount };
      }
    ),
    discountOfItem983;

discountOfItem983 = itemsAndDiscounts.
  filter
  (
    function(mapped) {
      return mapped.id === "983";
    }
  )
  [0].discount;

console.log("All items and discounts: " + JSON.stringify(itemsAndDiscounts, null, 2));

console.log("Discount of #983: " + discountOfItem983);

给出:

All items and discounts: [
  {
    "id": "984",
    "discount": "15"
  },
  {
    "id": "254",
    "discount": "15"
  },
  {
    "id": "983",
    "discount": "20"
  },
  {
    "id": "253",
    "discount": "20"
  }
]
Discount of #983: 20

以下是其他示例/用例:

JSON到一些的标记

JSON transformations, revisited (XSLT look-alike)

(at:https://jsfiddle.net/YSharpLanguage/kj9pk8oz/10

JSON到JSON

Super-lightweight JSON-to-JSON transformations

(at:https://jsfiddle.net/YSharpLanguage/ppfmmu15/10

相当于......的JavaScript

XSLT 3.0 REC Section 14.4 Example: Grouping Nodes based on Common Values

(at:http://jsfiddle.net/YSharpLanguage/8bqcd0ey/1

比照。 https://www.w3.org/TR/xslt-30/#grouping-examples

相当于......的JavaScript

JSONiq Use Cases Section 1.1.2. Grouping Queries for JSON

(at:https://jsfiddle.net/YSharpLanguage/hvo24hmk/3

比照。 http://jsoniq.org/docs/JSONiq-usecases/html-single/index.html#jsongrouping

'希望这有帮助,

答案 1 :(得分:0)

您可以编写一个返回父节点的函数。一旦你有了这个,你应该开发一个遍历(遍历)所有对象及其所有节点和数组的函数,当它找到所需的Id时,你就得到父代并检索折扣。

这里有一个返回父节点的函数的最简单示例:

<?xml version='1.0' encoding='utf-8'?>
<Context antiJARLocking="true" path="/APPNAME>
    <WatchedResource>WEB-INF/users.xml</WatchedResource>
</Context>
const myVar = {
  "prods": [{
    "info": {
      "rate": 100
    },
    "grocery": [{
        "brand": "A",
        "brand_id": "983",
        myParent: function() {
          const that = this; // to fix the caller instead of using 'bind' or 'apply'
          return that;
        }
      },
      {
        "brand": "B",
        "brand_id": "253",
        myParent: function() {
          const that = this;
          return that;
        }
      }
    ],
    "discount": "20"
  }]
}
function myFunction() {
    let x = document.getElementById("myNumber").value;
    let text = myVar.prods[0].grocery.find(el => el.brand_id === x).myParent().brand; 
    document.getElementById("demo").innerHTML = text;
}