views:

280

answers:

2

I'm using jQuery's .getJSON function to parse a set of search results from a Google Search Appliance. The search appliance has an xslt stylesheet that returns the results as JSON data, which I validated with both JSONLint and Curious Concept's JSON Formatter.

According to FireBug, the full result set is returned from the XMLHTTPRequest, but I tried dumping the data (with jquery.dump.js) and it only ever parses back the first result. It does successfully get all the Google Search Protocol stuff, but it only ever sees one "R" object (or individual result).

Has anybody had a similar problem with jQuery's .getJSON? I know it likes to fail silently if the JSON is not valid, but like I said, I validated the results with several validators and it should be good to go.

Edit: Clicking this link will show you the JSON results returned for a search for the word "google": http://bigbird.uww.edu/search?client=json_frontend&proxystylesheet=json_frontend&proxyrefresh=1&output=xml_no_dtd&q=google

jQuery only retrieves the first "R" object, even though all "R" objects are siblings.

+2  A: 

You might try doing "getJSON" yourself with your own "jsonpCallback" function. If the response from the API you're calling looks like a comma-separated list of JSON expressions, then the jQuery automatically-constructed callback function will only see the first one.

In other words, if the API returns

{something: "foo", whatever:23}, {something: "bar", whatever, 32}

then what'll end up in the response script block is:

magicJqueryCallback({something: "foo", whatever:23}, {something: "bar", whatever, 32})

The jQuery callback is declared as having just one argument, which it assigns to the "data" element of the fake XHR object.

Alternatively, if you have control over what the XSLT code does, you could have it wrap the list of responses in a set of square brackets, before it even gets to jQuery:

[{something: "foo", whatever:23}, {something: "bar", whatever, 32}]

If your XSLT produced that, it would (I hope) work just fine with getJSON.

edit OK, I see your problem now.

Your JSON response contains multiple values for "R" inside the outer object. That's not going to work: if "R" is a list, it needs to have a single value, with that value being an array.

  {"GSP": ..., "R":[{"U": ... }, {"U": ... }, {"U": ...}], ...}
Pointy
Yup. That's right. You just have to return ONE thing.
naugtur
Well, I'm not actually working with JSONP, as the Google Search Appliance doesn't provde the ability to do JSONP, so I'm just getting the raw JSON data through a simple little PHP proxy (tricking jQuery into thinking it's from the local server). I'll post an example of the data getting returned above.
Brad
Ah, that makes sense. I guess I (stupidly) assumed that the JSON being "validated" by the JS Lint / other validator meant it was good to go and I didn't have to think, ha ha. Makes sense that there can't be two elements with the same key.
Brad
Well it's interesting that the validator didn't at least give a warning, as it's not at all hard to detect that it's happening.
Pointy
True, maybe I'll e-mail the JS Lint guys to let them know that it's happening.
Brad
A: 

Alternatively you could always just use the $.ajax function and then simply eval the resulting JSON. I realize this is normally ill-advised but since you can be certain the Google Search Appliance won't inject an attack of any kind it could be used in this case.

Alex Winston
If he just used `eval()` it wouldn't help at all in this case. He'd have to implement a special JSON parser, which hardly seems worth it.
Pointy
Yeah, eval-ing the resulting data would just do the same thing as jQuery was already doing-- it would overwrite each "R" element to the next result, leaving only one. I re-worked the XSLT to name each "R" element by it's cardinal order instead of just calling them "R", and it's working properly now. :)
Brad