XPath is a neat way of navigating deep XML structures. It's like using a directory structure. /table//td gets all the TDs somewhere below TABLE.
Usually, you don't need this sort of a thing for data structures, particularly in JavaScript. Something like table.td would already work. But sometimes, it does help to have something like XPath even for data structures, so I built a simple XPath-like processor for Javascript called JPath.
Here are some examples of how it would work:
| jpath(context, "para") | returns context.para |
| jpath(context, "*") | returns all values of context (for both arrays and objects) |
| jpath(context, "para[0]") | returns context.para[0] |
| jpath(context, "para[last()]") | returns context.para[context.para.length] |
| jpath(context, "*/para") | returns context[all children].para |
| jpath(context, "/doc/chapter[5]/section[2]") | returns context.doc.chapter[5].section[2] |
| jpath(context, "chapter//para") | returns all para elements inside context.chapter |
| jpath(context, "//para") | returns all para elements inside context |
| jpath(context, "//olist/item") | returns all olist.item elements inside context |
| jpath(context, ".") | returns the context |
| jpath(context, ".//para") | same as //para |
| jpath(context, "//para/..") | returns the parent of all para elements inside context |
Some caveats:
There are a couple of reasons why this sort of thing is useful.
for (var list=[], i=0; i < data.length; i++) {
list.push(data[i][0]);
}
... or the short way:
$.map(data, function(v) {
return v[1];
})
But the best would be something like:
jpath(data, "//1")
{"responseData": {
"feed": {
"title": "Digg",
"link": "http://digg.com/",
"author": "",
"description": "Digg",
"type": "rss20",
"entries": [
{
"title": "The Pirate Bay Moves Servers to Egypt Due to Copyright Laws",
"link": "http://digg.com/tech_news/The_Pirate_Bay_Moves_Servers_to_Egypt_Due_to_Copyright_Laws",
"author": "",
"publishedDate": "Mon, 31 Mar 2008 23:13:33 -0700",
"contentSnippet": "Due to the new copyright legislation that are going ...",
"content": "Due to the new copyright legislation that are going to take...",
"categories": [
]
},
{
"title": "Millions Dead/Dying in Recent Mass-Rick-Rolling by YouTube.",
"link": "http://digg.com/comedy/Millions_Dead_Dying_in_Recent_Mass_Rick_Rolling_by_YouTube",
"author": "",
"publishedDate": "Mon, 31 Mar 2008 22:53:30 -0700",
"contentSnippet": "Click on any \u0022Featured Videos\u0022. When will the insanity stop?",
"content": "Click on any \u0022Featured Videos\u0022. When will the insanity stop?",
"categories": [
]
},
...
]
}
}
, "responseDetails": null, "responseStatus": 200}
If you wanted all the title entries, including the feed title, the choice is between:
var titles = [ result.feed.title ];
for (var i=0, l=result.feed.entries.length; i<l; i++) {
titles.push(result.feed.entries[i].title;
}
... versus...
titles = jpath(result, '//title');
If, further, you wanted the list of all categories at one shot, you could use:
jpath(result, "//categories/*")