Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue in management of alternates [q, r, ...] #114

Open
frmichel opened this issue Aug 21, 2015 · 6 comments
Open

Issue in management of alternates [q, r, ...] #114

frmichel opened this issue Aug 21, 2015 · 6 comments
Labels

Comments

@frmichel
Copy link

Hi again,

I have a second question.
Here is JSON document:
{ "p":{
"s": { "u": "su" },
"t": { "u": "tu" }
}}

Expression $.p.['t'].u returns "tu" => ok.
Expression $.p.['s', 't'].u returns nothing, I'd expect "su" and "tu".

Another document : { "p": ["valp", "valq", "valr"] }
Expression $.p[?(@[0] == 'valp')] returns nothing, I would expect ["valp", "valq", "valr"]
Expression $.p[?(@.length == 3)] returns nothing, I would expect ["valp", "valq", "valr"]

Am I mistaken or is there actually a bug somewhere?

Thx,
Franck.

@kallestenflo
Copy link
Contributor

The first issue:

$.p.['s', 't'].u returns nothing

In the current implementation you can only select multiple properties ['s', 't'] as the last part of a path. $.p.['s', 't'] works fine.

The second issue:

In the path $.p[?(@[0] == 'valp')] the @ represents the current element in the array and since your example is not an array of arrays this does not work. The intended use is $.p[?(@ == 'valp')]

Hope that makes sense.

@frmichel
Copy link
Author

Hi, thx for your reply.

In the current implementation you can only select multiple properties ['s', 't'] as the last part of a path. $.p.['s', 't'] works fine.

Ok for the limitation of field alternatives. Good to know.

About the use of @ indeed I'm afraid I'm confused with what "current element" really means depending on wether it is used in expressions [?(...)] or [(...)].
In the examples of the main project's README there is this example:

$..book[?(@.isbn)] All books with an ISBN number

Here indeed book is an array and @ refers to elements of the array.
Does this mean that expression p[?(...)] only works when p is an array?

But then, how would you write an expression to "select field p of any document in which there exists field q"? This was my initial intention when I wrote p[?(@.q)].

In $.p[(...)] the expression in () is a calculated index, assuming that p is necessarily an array.
In the examples of the main project's README there is this example:

$..book[(@.length-1)] : The last book

In that case @ refers to book, not to its elements. That is quite confusing compared to the [?()], isn't it?

Thx in advance, I really need to make sure I understand this! ;-)

Franck.

@kallestenflo
Copy link
Contributor

Expressions like [?(...)] can be used in the following contexts:

  • Filter array $.store.book[?(@.category == 'fiction')]
  • Scan $..[?(@.category == 'fiction')]
  • Match $.store.book[1][?(@.category == 'fiction')]

But then, how would you write an expression to "select field p of any document in which there exists >field q"? This was my initial intention when I wrote p[?(@.q)].

That can not be done.

$..book[(@.length-1)] : The last book

In that case @ refers to book, not to its elements. That is quite confusing compared to the [?()], isn't it?

I agree this is confusing. Think I will remove support for (@.length-1) because it can be achieved via $..book[-1:].

@zline
Copy link
Contributor

zline commented Oct 28, 2015

@frmichel first case now works as you expect

@frmichel
Copy link
Author

@zline Great thx!

@kallestenflo
Copy link
Contributor

Don't think I will get any further with this. Current state is described below and I think it works as expected. Thoughts on this?

@Test
public void issue_114_a() {
    String json = "{ \"p\":{\n" +
            "\"s\": { \"u\": \"su\" }, \n" +
            "\"t\": { \"u\": \"tu\" }\n" +
            "}}";

    List<String> result = JsonPath.read(json, "$.p.['s', 't'].u");
    assertThat(result).containsExactly("su","tu");
}

@Test
public void issue_114_b() {
    String json = "{ \"p\": [\"valp\", \"valq\", \"valr\"] }";

    List<String> result = JsonPath.read(json, "$.p[?(@ == 'valp')]");
    assertThat(result).containsExactly("valp");
}

@Test
public void issue_114_c() {
    String json = "{ \"p\": [\"valp\", \"valq\", \"valr\"] }";

    List<String> result = JsonPath.read(json, "$.p[?(@[0] == 'valp')]");
    assertThat(result).isEmpty();
}

@Test(expected = InvalidPathException.class)
public void issue_114_d() {
    JsonPath.read("[]", "$..book[(@.length-1)] ");
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants