JSON Path String Evaluation of root value - jsonpath

Have a service that returns a very basic json respons:
{
"methodresult": "error",
"ErrorCode": 2,
"ErrorCodeText": "format",
"ErrorMessage": "Json parse exception at pos:171 msg:Expecting \"key\""
}
And am trying to use JSONPath to query if the "methodresult" value is coming back as "error".
Based on the documentation/examples I've seen I would expect this to work:
$[?(#.methodresult=="error")]
However based on validators I'm utilizing like this (https://jsonpath.curiousconcept.com/) am not seeing any boolean response.
When trying to write an expression against something not in an array is there something I'm missing?

Include the json response within square brackets and it works.
[{
"methodresult": "error",
"ErrorCode": 2,
"ErrorCodeText": "format",
"ErrorMessage": "Json parse exception at pos:171 msg:Expecting \"key\""
}]
$[?(#.methodresult=="error")].methodresult
Result:
[
"error"
]

No, I don't think you are missing anything.
The problem is in the lack of a true standard for JSONPath. There are a few ideas/proposals (including a somewhat related one for JSON Pointer, which has been stuck in 'PROPOSED STANDARD' phase for years now), many implementations, and they are all different in some way even when they supposedly implement the same proposal (e.g. Stefan Goessner's one).
For example, when using Jayway JsonPath, these JSONPath expressions
$.[?(#.methodresult == 'error')]
$[?(#.methodresult == 'error')]
.[?(#.methodresult == 'error')]
[?(#.methodresult == 'error')]
produce the same result for the input JSON from the question:
{
"methodresult": "error",
"ErrorCode": 2,
"ErrorCodeText": "format",
"ErrorMessage": "Json parse exception at pos:171 msg:Expecting \"key\""
}
They return a non-empty array containing the JSON object that has methodresult field equal to error. And that is to be expected if one looks at Stefan Goessner's proposal...
Trying those same expressions for the given input here (link provided in the question) or here (which offers running a given JSONPath expression using 4 different implementations), and the results will be mixed: failed parsing, execution errors, an empty array, and sometimes as expected.
The bottom line is that, until there is a true standard for JSONPath, the only way to make sure a JSONPath expression works as expected is to write it for the concrete JSONPath implementation that you will be using in your application.

Related

JSONPath for matching child value

I've spent a lot of time trying to figure out how to write a json path which fits my needs, without success.
I hope someone will be able to help me.
I've got a very simple JSON object that looks like: {"code":..., "message":...}, note that this is not a list of objects
I'm trying to find a JSON path that returns [%code%] when code > 100, else [].
I've found $[?(#.code > 100)].code which works fine with Jayway & Gatling implementations, but doesn't with Nebahle and Goessner implementations (according to http://jsonpath.herokuapp.com/).
Sadly the project I'm working on is using a jsonpath lib with Goessner implementation.
Does anyone have an idea of a jsonpath that could work for any implementation?
Thanks!
There is no agreement between different JSONPath implementations for applying a filter expression to a JSON object. Some apply it to the object itself (e.g. Jayway), some apply it to each value of the JSON object (e.g. Goessner Javascript), and some don't seem to support it at all (e.g. Goessner PHP). Christoph Burgmer's JSONPath comparisons reports these differences here.
In your case, assuming Goessner Javascript, you might be able to get away with
$[?(#>100)] (1)
or perhaps safer
$[?(typeof(#) == 'number' && # > 100)] (2)
For example, given {"code":101, "message":"101"}, (1) produces
[101,"101"]
while (2) produces
[101]
(according to http://jsonpath.herokuapp.com/).

Making a throwable response to exception handling in R

I've turned my hand to R after many years of Java/C++. I am struggling to protect my operational flow using exception handling. Perhaps, I am looking at this with too much of a Java hat on.
Essentially, I am looking for a throw operator at the start of a function if a partiular argument to that function is incorrectly typed. An example for the structure (not functioning code) I am looking for:
myFunction <- function(someListArgument) {
if(class(someListArgument) != "List") {
throw(paste("Argument not a list: ", class(someListArgument)))
}
}
tryCatch({myFunction(c("whoops!"))},
error = function(cond) {},
....
)
I would really like the compartmentalisation of code as I am writing an R->MySQL DBMS API and I would like to keep well controlled and informative error reporting if incorrect datatypes are provided.

How do I fill up a list in this large piece of code?

I wrote this Parser incorrectly. My professor says that I am using the tokens inappropriately. The problem is that I'm trying to access the tokens from an empty list. How can I possibly fill up the list with tokens in order to make sure that the program analyzes the tokens so the Eiffel code can execute. That is why I am getting this error:
raised SYSTEM.ASSERTIONS.ASSERT_FAILURE : failed precondition from lexical_analyzers.ads:20
The code can be found here:
https://drive.google.com/file/d/0B3ZPyNRv7C3hV3NRUVBnN0prbEE/view?usp=sharing
The error comes from the lexical_analyzers.ads and the parsers.adb classes.
Your procedure Parse begins
procedure parse(p: in out Parser; f: out feature) is
tok: Token;
lex: Lexical_Analyzer;
var: Id;
com: Compound;
begin
so when you say
get_next_token(lex, tok);
which lex is it using? Answer: the empty one that you created in the declarations. You should be using p.lex.
And in the next line but one, your call to get_id doesn’t pass p:
var := get_id(tok);
and get_id repeats the pattern,
function get_id(tok: in Token) return Id is
par: Parser;
lex: Lexical_Analyzer;
tok1: Token := tok;
str: String := String(Tokens.get_lexeme(tok1));
begin
get_next_token(lex, tok1);
In this case, you’ve done it twice; you’ve created a local Parser and Lexical_Analyser instead of passing in the Parser (and its contained Lexical_Analyser).
This is a pattern you seem to have repeated in several places in the code.

print out xquery sequence and exit

Is there a way to "die" in execution flow in an xquery file and output a nicely formatted printout of a sequence variable?
I'm trying something like:
return { fn:error(xs:QName("ERROR"), $xml) }
but that doesn't quite seem to work.
Thanks!
Based on your comment (you need it for debugging) I guess you are looking for the fn:trace function, described here http://www.xqueryfunctions.com/xq/fn_trace.html
If you want to abort the execution flow and output an error in your application you should in fact use the XQuery exception handling.
Try something like this, omitting the return if this isn't part of a FLWOR expression.
...
return fn:error((), "DEBUG", $xml)
There's no need for curly braces unless you're enclosing an expression, for example <x>{ current-time() }</x>. The return expression is not enclosed.
With MarkLogic it's best to leave the first parameter of fn:error empty. That way you don't have to worry about a QName, and anyway some folks believe that it's reserved for predefined errors. MarkLogic uses the second parameter to fill in error:code, and the third parameter for data.
For more on fn:error, see http://docs.marklogic.com/fn:error and https://github.com/robwhitby/xray/pull/11

unitended reference comparision

I am getting this warning:
Possible unintended reference comparison; to get a value comparison, cast the left hand side to type 'string'
I tried this:
if (Convert.ToString(Session["message"]) == SESSIONTIMEOUT)
or
if (Session["message"].ToString() == SESSIONTIMEOUT)
But I'm still getting the above message.
You should use the Equals method for comparison of Strings, like this:
if (Session["message"].ToString().Equals(SESSIONTIMEOUT))
Generally speaking, the == operator is supposed to perform identity comparison - i.e., verifying that two object references point at the same object. See http://www.andymcm.com/csharpfaq.htm#6.7 for more information.
If you read the compiler warning message carefully, it says how you should solve it:
if ((string)Session["message"] == SESSIONTIMEOUT)
That's what casting the left hand side to string means, and this should be the solution. The reason why the message didn't go away, is that you didn't perform a complete rebuild (recompilation) of your project.
Now if there is any change the left hand side could be an object that's not a string, then use:
if (Session["message"] as string == SESSIONTIMEOUT)
but I guess you will not allow the type of your message to be non-string, so go for my first solution, the one suggested by the warning message.

Resources