···9Before diving in, it's worth understanding the difference between JSON
10Pointer and JSON Path, as they serve different purposes:
1112-{b JSON Pointer} (RFC 6901) is an {e indicator syntax} that specifies a
13{e single location} within JSON data. It always identifies at most one
14value.
15···4243{1 What is JSON Pointer?}
4445-From RFC 6901, Section 1:
4647{i JSON Pointer defines a string syntax for identifying a specific value
48within a JavaScript Object Notation (JSON) document.}
···8081{1 Syntax: Reference Tokens}
8283-RFC 6901, Section 3 defines the syntax:
8485{i A JSON Pointer is a Unicode string containing a sequence of zero or more
86reference tokens, each prefixed by a '/' (%x2F) character.}
···168169{1 Evaluation: Navigating JSON}
170171-Now we come to the heart of JSON Pointer: evaluation. RFC 6901, Section 4
172describes how a pointer is resolved against a JSON document:
173174{i Evaluation of a JSON Pointer begins with a reference to the root value
···176the document. Each reference token in the JSON Pointer is evaluated
177sequentially.}
178179-Let's use the example JSON document from RFC 6901, Section 5:
180181{x@ocaml[
182# let rfc_example = parse_json {|{
···326327{2 Array Index Rules}
328329-RFC 6901 has specific rules for array indices. Section 4 states:
330331{i characters comprised of digits [...] that represent an unsigned base-10
332integer value, making the new referenced value the array element with
···354355{1 The End-of-Array Marker: [-] and Type Safety}
356357-RFC 6901, Section 4 introduces a special token:
358359{i exactly the single character "-", making the new referenced value the
360(nonexistent) member after the last array element.}
361362This [-] marker is unique to JSON Pointer (JSON Path has no equivalent).
363-It's primarily useful for JSON Patch operations (RFC 6902) to append
364elements to arrays.
365366{2 Navigation vs Append Pointers}
···438439{1 Mutation Operations}
440441-While RFC 6901 defines JSON Pointer for read-only access, RFC 6902
442(JSON Patch) uses JSON Pointer for modifications. The [json-pointer]
443library provides these operations.
444···566567{1:escaping Escaping Special Characters}
568569-RFC 6901, Section 3 explains the escaping rules:
570571{i Because the characters '~' (%x7E) and '/' (%x2F) have special meanings
572in JSON Pointer, '~' needs to be encoded as '~0' and '/' needs to be
···623624{2 The Order Matters!}
625626-RFC 6901, Section 4 is careful to specify the unescaping order:
627628{i Evaluation of each reference token begins by decoding any escaped
629character sequence. This is performed by first transforming any
···646647{1 URI Fragment Encoding}
648649-JSON Pointers can be embedded in URIs. RFC 6901, Section 6 explains:
650651{i A JSON Pointer can be represented in a URI fragment identifier by
652encoding it into octets using UTF-8, while percent-encoding those
653-characters not allowed by the fragment rule in RFC 3986.}
654655This adds percent-encoding on top of the [~0]/[~1] escaping:
656···856- : Jsont.json = {"tasks":["buy milk","call mom"]}
857]x}
858859-This is useful for implementing JSON Patch ([RFC 6902]) where
860operations like ["add"] can target either existing positions or the
861append marker. If you need to distinguish between pointer types at runtime,
862use {!of_string_kind} which returns a polymorphic variant:
···870871{1 Summary}
872873-JSON Pointer (RFC 6901) provides a simple but powerful way to address
874values within JSON documents:
875876{ol
···878{- {b Escaping}: Use [~0] for [~] and [~1] for [/] in tokens (handled automatically by the library)}
879{- {b Evaluation}: Tokens navigate through objects (by key) and arrays (by index)}
880{- {b URI Encoding}: Pointers can be percent-encoded for use in URIs}
881-{- {b Mutations}: Combined with JSON Patch (RFC 6902), pointers enable structured updates}
882{- {b Type Safety}: Phantom types ([nav t] vs [append t]) prevent misuse of append pointers with retrieval operations, while the [any] existential type allows ergonomic use with mutation operations}
883}
884
···9Before diving in, it's worth understanding the difference between JSON
10Pointer and JSON Path, as they serve different purposes:
1112+{b JSON Pointer} ({{:https://datatracker.ietf.org/doc/html/rfc6901}RFC 6901}) is an {e indicator syntax} that specifies a
13{e single location} within JSON data. It always identifies at most one
14value.
15···4243{1 What is JSON Pointer?}
4445+From {{:https://datatracker.ietf.org/doc/html/rfc6901#section-1}RFC 6901, Section 1}:
4647{i JSON Pointer defines a string syntax for identifying a specific value
48within a JavaScript Object Notation (JSON) document.}
···8081{1 Syntax: Reference Tokens}
8283+{{:https://datatracker.ietf.org/doc/html/rfc6901#section-3}RFC 6901, Section 3} defines the syntax:
8485{i A JSON Pointer is a Unicode string containing a sequence of zero or more
86reference tokens, each prefixed by a '/' (%x2F) character.}
···168169{1 Evaluation: Navigating JSON}
170171+Now we come to the heart of JSON Pointer: evaluation. {{:https://datatracker.ietf.org/doc/html/rfc6901#section-4}RFC 6901, Section 4}
172describes how a pointer is resolved against a JSON document:
173174{i Evaluation of a JSON Pointer begins with a reference to the root value
···176the document. Each reference token in the JSON Pointer is evaluated
177sequentially.}
178179+Let's use the example JSON document from {{:https://datatracker.ietf.org/doc/html/rfc6901#section-5}RFC 6901, Section 5}:
180181{x@ocaml[
182# let rfc_example = parse_json {|{
···326327{2 Array Index Rules}
328329+{{:https://datatracker.ietf.org/doc/html/rfc6901}RFC 6901} has specific rules for array indices. {{:https://datatracker.ietf.org/doc/html/rfc6901#section-4}Section 4} states:
330331{i characters comprised of digits [...] that represent an unsigned base-10
332integer value, making the new referenced value the array element with
···354355{1 The End-of-Array Marker: [-] and Type Safety}
356357+{{:https://datatracker.ietf.org/doc/html/rfc6901#section-4}RFC 6901, Section 4} introduces a special token:
358359{i exactly the single character "-", making the new referenced value the
360(nonexistent) member after the last array element.}
361362This [-] marker is unique to JSON Pointer (JSON Path has no equivalent).
363+It's primarily useful for JSON Patch operations ({{:https://datatracker.ietf.org/doc/html/rfc6902}RFC 6902}) to append
364elements to arrays.
365366{2 Navigation vs Append Pointers}
···438439{1 Mutation Operations}
440441+While {{:https://datatracker.ietf.org/doc/html/rfc6901}RFC 6901} defines JSON Pointer for read-only access, {{:https://datatracker.ietf.org/doc/html/rfc6902}RFC 6902}
442(JSON Patch) uses JSON Pointer for modifications. The [json-pointer]
443library provides these operations.
444···566567{1:escaping Escaping Special Characters}
568569+{{:https://datatracker.ietf.org/doc/html/rfc6901#section-3}RFC 6901, Section 3} explains the escaping rules:
570571{i Because the characters '~' (%x7E) and '/' (%x2F) have special meanings
572in JSON Pointer, '~' needs to be encoded as '~0' and '/' needs to be
···623624{2 The Order Matters!}
625626+{{:https://datatracker.ietf.org/doc/html/rfc6901#section-4}RFC 6901, Section 4} is careful to specify the unescaping order:
627628{i Evaluation of each reference token begins by decoding any escaped
629character sequence. This is performed by first transforming any
···646647{1 URI Fragment Encoding}
648649+JSON Pointers can be embedded in URIs. {{:https://datatracker.ietf.org/doc/html/rfc6901#section-6}RFC 6901, Section 6} explains:
650651{i A JSON Pointer can be represented in a URI fragment identifier by
652encoding it into octets using UTF-8, while percent-encoding those
653+characters not allowed by the fragment rule in {{:https://datatracker.ietf.org/doc/html/rfc3986}RFC 3986}.}
654655This adds percent-encoding on top of the [~0]/[~1] escaping:
656···856- : Jsont.json = {"tasks":["buy milk","call mom"]}
857]x}
858859+This is useful for implementing JSON Patch ({{:https://datatracker.ietf.org/doc/html/rfc6902}RFC 6902}) where
860operations like ["add"] can target either existing positions or the
861append marker. If you need to distinguish between pointer types at runtime,
862use {!of_string_kind} which returns a polymorphic variant:
···870871{1 Summary}
872873+JSON Pointer ({{:https://datatracker.ietf.org/doc/html/rfc6901}RFC 6901}) provides a simple but powerful way to address
874values within JSON documents:
875876{ol
···878{- {b Escaping}: Use [~0] for [~] and [~1] for [/] in tokens (handled automatically by the library)}
879{- {b Evaluation}: Tokens navigate through objects (by key) and arrays (by index)}
880{- {b URI Encoding}: Pointers can be percent-encoded for use in URIs}
881+{- {b Mutations}: Combined with JSON Patch ({{:https://datatracker.ietf.org/doc/html/rfc6902}RFC 6902}), pointers enable structured updates}
882{- {b Type Safety}: Phantom types ([nav t] vs [append t]) prevent misuse of append pointers with retrieval operations, while the [any] existential type allows ergonomic use with mutation operations}
883}
884