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

Documentations for .. operator #1337

Closed
fadado opened this issue Feb 11, 2017 · 6 comments
Closed

Documentations for .. operator #1337

fadado opened this issue Feb 11, 2017 · 6 comments
Labels

Comments

@fadado
Copy link

fadado commented Feb 11, 2017

If you follow the description for the operator .. in the manual you are redirected to the definition of recurse , then to recurse(.[]?), then to recurse(f; . != null)...

I propose the following equivalence:

..

Short-hand for ., .[]?, (.[]?|.[]?), (.[]?|.[]?|.[]?), ....

@nicowilliams
Copy link
Contributor

Hmmm, how about:

      Recursively descends `.`.  Same as `recurse` without
      arguments.  This is intended to resemble the XPath `//`
      operator.  Note that `..a` does not work; use `..|.a` instead.
      In the example below we use `..|.a?` to find all the values of
      object keys "a" in any object found "below" `.`.

      This is particularly useful in conjunction with `path(EXP)`
      and the `?` operator.

@fadado
Copy link
Author

fadado commented Feb 14, 2017

Hmmm, how about:

  Recursively descends `.`

Very good.

I will reuse this tread for other documentation confusing aspects:

  1. Defining error(message) the manual says Produces an error. A will say signals or raises, reserving produces for filters. By the way, error accepts all kind of values as argument, not only strings: this must be clarified.

  2. Defining array access the manual says used with the slice operator. Is slicing an operator? In coherence with the manual it is a syntax or filter, not an operator.

Thanks in advance for your attention.

@nicowilliams
Copy link
Contributor

To be absolutely pure, we have just these types of things in jq:

  • special operations that can only possibly be implemented with special syntax (e.g., EXP as $name | ..., reduce, ...)
  • special operations supported by the bytecode opcodes and syntax (e.g., .[] being implemented as the EACH opcode; the compiler maps .[] to EACH)
    • things like + also fall into this category -- the compiler converts them into calls to the _plus (etcetera) builtins
  • special operations supported by the bytecode opcodes and byte-coded builtins (e.g., empty, path)
  • special operations supported by C-coded builtins (e.g., math functions)
  • jq-coded builtins

Some of these things look like "operators": +, -, and so on. While others look like something other than operators (e.g., EXP as $name | ..., reduce, ...). The rest look like functions (e.g., empty).

So perhaps we can say we have three kinds of things:

  • syntax
  • operators
  • functions

Am I missing anything?

@nicowilliams
Copy link
Contributor

See #1340 for modest improvements related to this.

@chilversc
Copy link

I found the basic example for recursive decent to be be inadequate for translating a basic xpath query.

Xml Example

<?xml version="1.0" encoding="UTF-8"?>
<Operations> 
  <Operation> 
    <Source> 
      <Url>"http://example.com/source"</Url> 
    </Source>  
    <Target> 
      <Url>"http://example.com/target"</Url> 
    </Target> 
  </Operation> 
</Operations>

The query //Target/Url/text() results in "http://example.com/target".

JSON Example

{
    "operations": [
        {
            "source": {
                "url": "http://example.com/source"
            },
            "target": {
                "url": "http://example.com/target"
            }
        }
    ]
}

From the documentation it sounds like you would translate that query to something like .. | .target.url. However that will result in the error Cannot index array with string "target".

One might then try adding the ? qualifier, thus .. | .target?.url but this then results in an output that also contains non-matching nodes with the value null along side the desired value.

As such the .. isn't at all similar to the xpath // operator and needs additional filtering to get anything similar to it.

I think this more accurately implements the example XPath:

.. | select(type=="object" and has("target")) | .target.url

If you're not expecting the property to have an explicit null value it can be shortened to:

.. | .target?.url | select(. != null)

Though in both cases this is a lot more verbose and awkward than the // operator from XPath if you're trying to quickly extract a value from a document at the command line.

http://www.xpathtester.com/xpath/c20db524c674d186e188c454794fd34d
https://jqplay.org/s/q5uCkpq5_6
https://jqplay.org/s/tL6DjDgmis

@itchyny itchyny added the docs label Jun 3, 2023
@itchyny
Copy link
Contributor

itchyny commented Jun 17, 2023

The document for the operator has been improved in 9b21790 so closing.

@itchyny itchyny closed this as completed Jun 17, 2023
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

4 participants