dfilatov/jspath

Selecting variables and from variables

Closed this issue · 16 comments

hoho commented

I can do something like JSPath.apply('.aa{$bb === 2}', {aa: 1}, {bb: 2}).

It would be nice to be able to do something like JSPath.apply('.aa{$bb.cc === 2}', {aa: 1}, {bb: {cc: 2}}) and JSPath.apply('$aa', {}, {aa: [1,2,3]}).

@hoho I tried to understand your examples, but I didn't manage. Why do you need to select .aa with predicate ($bb.cc === 2}) on another object?
Maybe you could you provide more realistic ones?

hoho commented

JSPath.apply('$param', {}, {param: {aa: 11, bb: 22}} -> {aa: 11, bb: 22}
JSPath.apply('$param.aa', {}, {param: {aa: 11, bb: 22}} -> [11]
JSPath.apply('$param.*', {}, {param: {aa: 11, bb: 22}} -> [11, 22]
JSPath.apply('.cc | $param.bb', {cc: 33}, {param: {aa: 11, bb: 22}} -> [33, 22]

Let's take your first example: JSPath.apply('$param', {}, {param: {aa: 11, bb: 22}}) -> {aa: 11, bb: 22}
At first $param inside path is replaced by {param: {aa: 11, bb: 22}}. Then the resulting path (as object?) is applied to {}. What does it mean?

It seems I've actually been missing something you want to achieve.

hoho commented

This is an example from readme:

var path = '.books{.author.name === $author}.title';
JSPath.apply(path, doc, { author : ['Robert C. Martin', 'Douglas Crockford'] });
/* ['Clean Code', 'Agile Software Development', 'JavaScript: The Good Parts'] */

I want something like XPath variables.

var path = '.books{.author.name === $author | .author.name === $author2}.title | $data..key1';
JSPath.apply(path, doc, {
    author: 'Robert C. Martin',
    author2: 'Douglas Crockford',
    data: {
        key1: 123,
        key2: {
            key1: 435
        }
    }
});
/* ['Clean Code', 'Agile Software Development', 'JavaScript: The Good Parts', 123, 456] */

Or just an ability to select variable value:

JSPath.apply('$author', doc, {author : ['Robert C. Martin', 'Douglas Crockford']});
/* ['Robert C. Martin', 'Douglas Crockford'] */

JSPath.apply('$author[1]', doc, {author : ['Robert C. Martin', 'Douglas Crockford']});
/* 'Douglas Crockford' */

Why don't you want to have data as data, not as variable?

JSPath.apply('.author[1]', {author : ['Robert C. Martin', 'Douglas Crockford']});
/* 'Douglas Crockford' */
hoho commented

I do want to have it and I'm having it. But just for the same reason XSLT variables exist — context data is not always enough. I'm trying to make a DSL to build JSON trees from other JSON trees. I'm starting with something like this: https://github.com/hoho/dryad. And I sense that an ability to address variables from JSPath expressions would be really useful.

Why is context data not enough? You're able to construct context as needed, something like this:

JSPath.apply(
    path,
    {
        mainData : data
        otherData : otherData,
        otherData2 : otherData2
    });

Then you can refer to any part of data within path via absolute locator: ^.mainData, ^.otherData, ^.otherData2.
Thus you don't need to split your data to data and variables.

hoho commented

That's not it semantically. I have the context data and I have some other datas, from other sources, dynamically constructed. Just the same to XSLT — you have the context XML tree and you have variables you can construct on the run and pass as the parameters to other templates. For example, tree2 function from https://github.com/hoho/dryad readme (I've added some comments) — there is the context data and there are arguments. It would be semantically straightforward to address arguments by the same names in JSPath queries and to query the context data with direct JSPath queries.

hoho commented

Another good reason is to pass more complex environment structures. Something like:

var path = '.books{.author.name ^== $author.first}.title';
JSPath.apply(path, doc, {author: [{first: 'Robert', last: 'C. Martin'}, {first: 'Douglas', last: 'Crockford'}]});

Yes, the context data could be rearranged somehow. But I'm about to make a tool for rearranging the data and it is strange to rearrange the data for the tool that aims to rearrange the data.

I guess it is logical to have this, especially when XPath was the source of inspiration (a variable could have a nodeset value and in such case this nodeset elements are addressable from XPath expressions).

And just to have it straight — you object because you want to see a good use case for the feature or you object because it is hard to implement? :)

At first look it's not difficult to implement. I'm just trying to realise that it really needs to do :)

Will be implemented in 0.3

hoho commented

👍

@hoho I've released 0.3.0, could you check whether it works as you expected?

hoho commented

Cool! I'm onto testing it.

hoho commented

From the first sight looks as expected. #29 too. Thanks a lot!

@hoho Thank you for participating!