Skip to content

Search Keyword: name

William W. Kimball, Jr., MBA, MSIS edited this page May 5, 2021 · 2 revisions
  1. Introduction
    1. Syntax
    2. Sample Data
  2. Hash Key Names
  3. Array Element Indexes

Introduction

The [name()] search keyword will yield the name of the present Hash (map/dict) key or the index of the present Array (sequence/list) element. This cannot be inverted. This is especially useful for returning the name of matched Hash children, particularly when paired with the [parent([STEPS]) search keyword for complex data structures and queries.

Syntax

[name()] accepts no parameters. It operates only against the present data node.

Sample Data

To illustrate what this search keyword does, consider the following sample data, named name-examples.yaml:

---
hash:
  with:
    children: having
    properties: and
    enabled: [M,W,F]
  values:
    in: a
    complex: structure
    enabled: [T,R]
  anywhere:
    in: any
    compatible: data
    enabled: [S,U]
  searchable:
    using: simple
    yaml: paths
    enabled: [S,M,W,F]

array:
  - with
  - several
  - elements

Hash Key Names

A query like the following doesn't yield any more information than you already knew:

$ yaml-get --query='/hash/with/children[name()]' name-examples.yaml
children

The query author already knew the name of the target node, children. So, this doesn't really yield anything new.

But what if you need the names of Hash keys that you don't know in advance? Consider for example: Which of the hash entities in the sample data are enabled on Wednesday (W)? Try this:

$ yaml-get --query='/hash/**[enabled=W][parent(2)][name()]' name-examples.yaml
with
searchable

You can visually confirm that the with and searchable entities are in fact enabled on Wednesday. Let's break that query and its result down to understand how it works.

First, we know that need to match child entities of the hash data structure, so we set the query to start at the hash key of the document root: /hash. Alone, that yields the entire contents of the hash Hash:

$ yaml-get --query='/hash' name-examples.yaml
{"with": {"children": "having", "properties": "and", "enabled": ["M", "W", "F"]}, "values": {"in": "a", "complex": "structure", "enabled": ["T", "R"]}, "anywhere": {"in": "any", "compatible": "data", "enabled": ["S", "U"]}, "searchable": {"using": "simple", "yaml": "paths", "enabled": ["S", "M", "W", "F"]}}

Then, we cheat a little bit by employing a deep traversal on an assumption about the particular structure of this data: **.

$ yaml-get --query='/hash/**' name-examples.yaml
having
and
M
W
F
a
structure
T
R
any
data
S
U
simple
paths
S
M
W
F

That's way too much data! Since we're only interested in enabled conditions, filter the query to yield only that data:

$ yaml-get --query='/hash/**/enabled' name-examples.yaml
["M", "W", "F"]
["T", "R"]
["S", "U"]
["S", "M", "W", "F"]

That's a lot more manageable, but still needs to be filtered to only entities that are enabled on Wednesday. So, filter the traversal results further using a search expression that says, "match only when there is an enabled key having exactly a W value:

$ yaml-get --query='/hash/**[enabled=W]' name-examples.yaml
W
W

We can see now that there are exactly two entities that are enabled on Wednesday, but which ones are they? Step up one level to investigate:

yaml-get --query='/hash/**[enabled=W][parent()]' name-examples.yaml
["M", "W", "F"]
["S", "M", "W", "F"]

Well, that is the entire enabled data for each entity which is enabled on Wednesday, but still not high enough in the data hierarchy to tell us which entities have matched, by name. Step up another parent level:

yaml-get --query='/hash/**[enabled=W][parent(2)]' name-examples.yaml
{"children": "having", "properties": "and", "enabled": ["M", "W", "F"]}
{"using": "simple", "yaml": "paths", "enabled": ["S", "M", "W", "F"]}

That finally looks like the entirety of the entities we are interested in, but we still need their names. Tell the YAML Path to yield only the names of the present, matched entities:

yaml-get --query='/hash/**[enabled=W][parent(2)][name()]' name-examples.yaml
with
searchable

And we have our answer!

Array Element Indexes

Perhaps less interesting, the [name()] search keyword can also yield the exactly element index at which an Array (sequence/list) match exists at. This isn't especially useful when you already know the index of any particular element, as with:

$ yaml-get --query='/array[1]' name-examples.yaml
several

$ yaml-get --query='/array[1][name()]' name-examples.yaml
1

Remember that YAML Path uses zero-based indexing, so element 1 is the second element in the Array. Further, we clearly already knew that "element at index 1 is indeed at index 1". But what if we don't already know the index and we need to know? Imagine a scenario where we somehow needed to know at exactly which element index(es) our sample Array held values containing the letter e. We'd answer that using:

$ yaml-get --query='/array/*e*[name()]' name-examples.yaml
1
2

For fun, what if we needed the index of elements containing both an e and an m? Try this:

yaml-get --query='(/array/*e*)*m*[name()]' name-examples.yaml
2

This scary-looking YAML Path is actually really simple. It Collects into a list all elements in the sample Array which contain a letter e. It then filters that list to match only the results which also contain a letter m. It then finally returns only the index of the matches within the sample Array. Easy!

Clone this wiki locally