Skip to content

YAML Path versus JSONPath

William W. Kimball, Jr., MBA, MSIS edited this page Nov 14, 2022 · 3 revisions

Introduction

Self-described as "XPath for JSON", the JSONPath specification dictates a particular dialect for selecting data nodes from JSON-encapsulated data. It also offers implementations of its specification in both JavaScript and PHP.

There are several topics to discuss when contrasting YAML Path with JSONPath, including:

  • the relationship between JSON and YAML;
  • contrast JSONPath and YAML Path syntax;
  • demonstrate addressing capabilities of both; and
  • discuss their reference implementations.

Relationship Between JSON and YAML

YAML is a superset of JSON. This means that YAML processors -- like YAML Path -- are wholly compatible with JSON data; they are fully capable of reading and writing JSON and YAML. Being a superset, this also means that YAML offers more capabilities than JSON alone.

Syntax

While JSONPath compares itself most closely to XPath when discussing its syntax, it does not employ the familiar / (forward-slash) segment separator from XPath. Rather, JSONPath offers two different separator styles: a . (dot) separator or "bracket notation" where each segment is individually demarcated via a [] (square-bracket) pair. Like XPath's forward-slash, when using the dot separator, the JSONPath dot separator is expected before the first segment. Unlike XPath, JSONPath also mandates a prefix of $ to indicate the path root, like $.segment1.segment2.segmentN or $['segment1']['segment2']['segmentN'].

YAML Path also offers two different separator styles: . (dot) or / (forward-slash). With regard to the forward-slash, YAML Path more closely matches XPath than JSONPath does. There is no need for a $ prefix with YAML Path. When using dot-notation, a YAML Path needn't start with a dot, but doing so anyway is harmless (a leading dot is ignored).

Separator XPath JSONPath YAML Path
/ /segment1/segment2/segmentN N/A /segment1/segment2/segmentN
. Address the present node $.segment1.segment2.segmentN segment1.segment2.segmentN
[] Demarcate Expressions $['segment1']['segment2']['segmentN'] Demarcate Expressions

Addressing Capabilities

YAML Path is more comprehensive in its addressing capabilities than is JSONPath, owing primarily to the additional capabilities of YAML. Neither YAML Path nor JSONPath are as comprehensive as XPath is. For a side-by-side contrast in JSONPath's own terms, the following table is copied -- and expanded -- from the same table found at the JSONPath site:

XPath JSONPath YAML Path Description
/ $ / when using forward-slash notation, nothing for dot notation The root object/element
. @ . The current object/element
/ . or [] / or . Child operator
.. N/A [parent([STEPS])] Parent operator
max(), min() N/A [max(NAME)], [min(NAME)] (Search Keywords) Aggregate functions
name() N/A [name()] (Search Keywords) Name of the present node; YAML Path also uses this to reveal the index of the present element
*[NAME] N/A [has_child(NAME)] Select nodes having a NAMEd child
// .. ** Recursive descent
* * * Wildcard
@ N/A N/A Attribute access; neither JSON nor YAML have attributes
[] [] [] Subscript operator
() N/A () (Collectors) Grouping
| [,] ()+() (Collector Math) Union operator
except N/A ()-() (Collector Math) Difference (subtraction) operator
intersect N/A ()&() (Collector Math) Intersection operator
N/A [start:end:step] [start:end] Array slice operator
[] ?() [] (Search Expressions) Filter (script) expression
N/A () N/A Script expression, using the underlying script engine
N/A N/A & Anchor/Alias/YAML Merge Key name matching
>, <, >=, <=, =, != >, <, >=, <= >, <, >=, <=, =, != (Search Expressions) Comparison operators
matches() N/A =~ Regular Expression matches

YAML Path also provides other robust node selection capabilities like Pass-Through Selections for Arrays of Hashes, Hash Slices, and other Search Expression operators.

By Example

For a side-by-side comparison of JSONPath and YAML Path, consider the following examples from the JSONPath documentation with YAML Paths added.

Sample Data:

{ "store": {
    "book": [ 
      { "category": "reference",
        "author": "Nigel Rees",
        "title": "Sayings of the Century",
        "price": 8.95
      },
      { "category": "fiction",
        "author": "Evelyn Waugh",
        "title": "Sword of Honour",
        "price": 12.99
      },
      { "category": "fiction",
        "author": "Herman Melville",
        "title": "Moby Dick",
        "isbn": "0-553-21311-3",
        "price": 8.99
      },
      { "category": "fiction",
        "author": "J. R. R. Tolkien",
        "title": "The Lord of the Rings",
        "isbn": "0-395-19395-8",
        "price": 22.99
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 19.95
    }
  }
}
XPath JSONPath YAML Path Result
/store/book/author $.store.book[*].author /store/book/author the authors of all books in the store
//author $..author /**/author all authors
/store/* $.store.* /store/* all things in store, which are some books and a red bicycle
/store//price $.store..price /store/**/price the price of everything in the store
//book[3] $..book[2] /**/book[2] the third book
//book[last()] $..book[(@.length-1)], $..book[-1:] /**/book[-1] the last book in order
//book[position()<3] $..book[0,1], $..book[:2] /**/book[0:2] the first two books
//book[isbn] $..book[?(@.isbn)] /**/book[.=isbn] filter all books with ISBN Number
//book[price<10] $..book[?(@.price<10)] /**/book[price<10] filter all books cheaper than 10
//* $..* /** every node in the data

Security Consideration

It should be noted that both of the JavaScript and PHP reference implementations of JSONPath internally use the eval function to execute arbitrary code passed along as a segment of a JSONPath. The reference implementation for YAML Path does not. There is ample public domain information discouraging the use of eval, especially when evaluating user-supplied code.

In addition, the JSONPath project seems to be dead. It's last release was in February 2008, despite its author listing some ideas for future work on its primary website.

Clone this wiki locally