2

I have the following json

{
    "id": "0001",
    "type": "donut",
    "name": "Cake",
    "ppu": 0.55,
    "batters": {
        "batter": [
                { "id": "1001", "type": "Regular" },
                { "id": "1002", "type": "Chocolate" },
                { "id": "1003", "type": "Blueberry" },
                { "id": "1004", "type": "Devil's Food" }
            ]
    },
    "topping": [
        { "id": "5001", "type": "None" },
        { "id": "5002", "type": "Glazed" },
        { "id": "5005", "type": "Sugar" },
        { "id": "5007", "type": "Powdered Sugar" },
        { "id": "5006", "type": "Chocolate with Sprinkles" },
        { "id": "5003", "type": "Chocolate" },
        { "id": "5004", "type": "Maple" }
    ]
}

I am trying to pass an xpath as a variable.

$(document).ready(function(){
    var json_offset = 'topping.types'
    ...
    $.getJSON('json-data.php', function(data) {
        var json_pointer = data.json_offset;
        ...
    });
});

Which dosn't work. Can anyone help?

Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
tnt-rox
  • 5,400
  • 2
  • 38
  • 52

3 Answers3

3
// This won’t work:
var json_offset = 'topping.types';
var json_pointer = data.json_offset;
// Here, you attempt to read the `data` object’s `json_offset` property, which is undefined in this case.

// This won’t work either:
var json_offset = 'topping.types';
var json_pointer = data[json_offset];
// You could make it work by using `eval()` but that’s not recommended at all.

// But this will:
var offsetA = 'topping',
    offsetB = 'types';
var json_pointer = data[offsetA][offsetB];
Mathias Bynens
  • 144,855
  • 52
  • 216
  • 248
3

Something like that should work (I didn't actually test it, tho):

Object.getPath = function(obj, path) {
    var parts = path.split('.');
    while (parts.length && obj = obj[parts.shift()]);
    return obj;
}
// Or in CoffeeScript:
// Object.getPath = (obj, path) -> obj=obj[part] for part in path.split '.'; obj

Than, use it like that:

Object.getPath(data, json_offset)

However, unless the path is dynamic and you can't, you should simply use data.topping.types. Also, you referred to that path as "XPath", but XPath is a very different thing that has nothing to do with you're trying to do.

shesek
  • 4,584
  • 1
  • 28
  • 27
  • You welcome. I edited it a bit - there's no need to use another `current` variable, it can be done directly with `obj`, and I added a CoffeeScript version just for the heck of it – shesek Sep 05 '11 at 09:18
1

Something like this works if it's dynamic.

var root = data;
var json_offset = 'topping.types';
json_offset = json_offset.split('.');

for(var i = 0; i < path.length - 1; i++) {
  root = root[json_offset[i]];
}

var json_pointer = root[path[json_offset.length - 1]];
mauteri
  • 531
  • 3
  • 7