{"id":22750057,"url":"https://github.com/pwall567/kjson-pointer","last_synced_at":"2025-04-14T12:54:44.676Z","repository":{"id":57735728,"uuid":"391795810","full_name":"pwall567/kjson-pointer","owner":"pwall567","description":"JSON Pointer for Kotlin","archived":false,"fork":false,"pushed_at":"2025-02-06T13:29:05.000Z","size":105,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-28T02:05:04.420Z","etag":null,"topics":["json","kotlin"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pwall567.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-08-02T02:39:34.000Z","updated_at":"2025-02-06T12:02:52.000Z","dependencies_parsed_at":"2024-12-11T04:12:05.636Z","dependency_job_id":"2b438200-63e2-4291-8388-eba82cc1db01","html_url":"https://github.com/pwall567/kjson-pointer","commit_stats":null,"previous_names":[],"tags_count":50,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pwall567%2Fkjson-pointer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pwall567%2Fkjson-pointer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pwall567%2Fkjson-pointer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pwall567%2Fkjson-pointer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pwall567","download_url":"https://codeload.github.com/pwall567/kjson-pointer/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248885659,"owners_count":21177627,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["json","kotlin"],"created_at":"2024-12-11T04:11:51.115Z","updated_at":"2025-04-14T12:54:44.665Z","avatar_url":"https://github.com/pwall567.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# kjson-pointer\n\n[![Build Status](https://github.com/pwall567/kjson-pointer/actions/workflows/build.yml/badge.svg)](https://github.com/pwall567/kjson-pointer/actions/workflows/build.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Kotlin](https://img.shields.io/static/v1?label=Kotlin\u0026message=v2.0.21\u0026color=7f52ff\u0026logo=kotlin\u0026logoColor=7f52ff)](https://github.com/JetBrains/kotlin/releases/tag/v2.0.21)\n[![Maven Central](https://img.shields.io/maven-central/v/io.kjson/kjson-pointer?label=Maven%20Central)](https://search.maven.org/search?q=g:%22io.kjson%22%20AND%20a:%22kjson-pointer%22)\n\nKotlin implementation of [JSON Pointer](https://tools.ietf.org/html/rfc6901).\n\nNote \u0026ndash; **Breaking Change** \u0026ndash; from version 8.0 of the library, the basic functions of the `JSONPointer` class\n(along with `JSONPointerException`) have been moved to a new library\n[`kjson-pointer-core`](https://github.com/pwall567/kjson-pointer-core), allowing the class to be used independently of\nany specific JSON implementation.\n\nThat leaves this library with the responsibility of applying the functionality of the `JSONPointer` class to the JSON\nstructures created by the [`kjson-core`](https://github.com/pwall567/kjson-core) library.\nThe `find()` and `existsIn()` and all the other functions that apply a `JSONPointer` to a `JSONValue` structure are now\nimplemented as extension functions on `JSONPointer`, leaving the `kjson-pointer-core` library free of dependencies that\nare needed only for these operations.\nFor existing users of the library, the switch to the use of extension functions means that some functions will now need\nto be imported, where previously they were part of the `JSONPointer` class.\n\nThe `JSONRef` and `JSONReference` classes both include references to `JSONValue` objects, so they remain part of this\nlibrary.\n\nNote \u0026ndash; **Breaking Change** \u0026ndash; from version 5.0 of the library, the `tokens` array is no longer accessible as\na `public` value.\nIt was an oversight to allow it to be accessible previously since array members may be modified, and a `JSONPointer` is\nintended to be immutable.\nThe array of tokens may be obtained by the functions `tokensAsArray()` which returns a copy of the array, or\n`tokensAsList()` which returns an immutable `List`.\n\nNote \u0026ndash; **Breaking Change** for users of the `toURIFragment()` and `fromURIFragment()` functions \u0026ndash; from\nversion 4.0 of the library, these functions no longer output or expect the leading `#` symbol.\n\n\n\n## Quick Start\n\n### `JSONPointer`\n\n#### Core Functions\n\nThe details on creating a `JSONPointer`, and then using that pointer to navigate to locations in a JSON structure\nrelative to the original pointer, are now described in the\n[`kjson-pointer-core`](https://github.com/pwall567/kjson-pointer-core) library, but to summarise:\n\nTo create a pointer from a JSON Pointer string (which may include encoding of \u0026ldquo;`/`\u0026rdquo; and \u0026ldquo;`~`\u0026rdquo;\ncharacters, as described in the [JSON Pointer Specification](https://tools.ietf.org/html/rfc6901)):\n```kotlin\n    val pointer = JSONPointer(\"/prop1/0\")\n```\nAlternatively, the companion object functions `JSONPonter.of()` and `JSONPointer.from()` will create a `JSONPointer`\nfrom a pointer string, a `vararg` array of tokens, or a `List` or `Array` of tokens.\n\nTo use a `JSONPointer` to create a new pointer referring to a child element:\n```kotlin\n    val childPointer = pointer.child(childRef)\n```\n(where `childRef` is a string to select a property from an object, a number to select an array item, or another\n`JSONPointer` to create a pointer to a more deeply nested element).\n\nTo use a `JSONPointer` to create a new pointer referring to the parent element:\n```kotlin\n    val childPointer = pointer.parent()\n```\n\nObjects of the `JSONPointer` class are immutable, so the above functions all create a new instance.\n\n#### Dereferencing\n\nThe functions to use a `JSONPointer` to locate elements within a JSON structure created by the `kjson-core` library are\nimplemented as extension functions in this library.\n\nTo test whether an element referenced by the pointer exists in the JSON object `obj`:\n```kotlin\n        if (pointer existsIn obj) {\n            doSomething(obj, pointer)\n        }\n```\nAlternatively:\n```kotlin\n        if (obj.contains(pointer)) {\n            doSomething(obj, pointer)\n        }\n```\nEither of these two constructs returns `false` if the `obj` is `null`.\n\nTo retrieve the element:\n```kotlin\n        val value = pointer.find(obj)\n```\nThis will throw a `JSONPointerException` if the pointer is not valid for the given structure, so it is generally wise to\ntest whether the element exist using one of the tests above.\n\nAn alternative is to use the indexing operation \u0026ndash; this will return `null` if no element exists at the pointer\nlocation:\n```kotlin\n        val value = obj[pointer]\n```\n\nTo create a pointer to a specified child value within a structure:\n```kotlin\n        val childPointer = pointer.locateChild(structure, target)\n```\n(This will perform a depth-first search of the JSON structure, so it should be used only when there is no alternative.)\n\n\n### `JSONReference`\n\nA `JSONReference` is a combination of a `JSONPointer` and a `JSONValue`.\nThis can be valuable when navigating around a complex tree \u0026ndash; it removes the necessity to pass around both a\npointer and the base value to which it refers, and it pre-calculates the destination value (and its validity).\n\n(`JSONReference` has since been superseded by [`JSONRef`](#jsonref), and may eventually be deprecated.)\n\nTo create a `JSONReference` to the root of an object:\n```kotlin\n        val ref = JSONReference(base)\n```\n\nOr to create a reference to a location in an object specified by a pointer:\n```kotlin\n        val ref = JSONPointer(\"/field\") ref base\n```\n\nThe `parent()` and `child()` operations work on `JSONReference`s similarly to their `JSONPointer` equivalents.\n\nTo get the value from a `JSONReference` (the value within the base object pointed to by the pointer part of the\nreference):\n```kotlin\n        val value: JSONValue? = ref.value // may be null\n```\n\nTo test whether the reference is valid, that is, the pointer refers to a valid location in the base object:\n```kotlin\n        if (ref.valid) {\n            doSomething(ref)\n        }\n```\n\nTo test whether the reference has a nominated child:\n```kotlin\n        if (ref.hasChild(name)) { // or index\n            doSomething(ref, name)\n        }\n```\n\nTo create a reference to a specified target child value:\n```kotlin\n        val childRef = baseRef.locateChild(target)\n```\n(This will perform a depth-first search of the JSON structure, so it should be used only when there is no alternative.)\n\n\n### `JSONRef`\n\n`JSONRef` is an evolution of the concept first implemented in [`JSONReference`](#jsonreference).\nLike the earlier class, it combines a `JSONPointer` with the object into which the pointer navigates, but, as a\nparameterised class, it allows the target element to be accessed in a type-safe manner.\n\nThe parameter class may be any of the `JSONValue` sealed interface types (or their nullable forms):\n- `JSONString`\n- `JSONInt`\n- `JSONLong`\n- `JSONDecimal`\n- `JSONNumber`: `JSONInt`, `JSONLong` or `JSONDecimal`\n- `JSONBoolean`\n- `JSONPrimitive`: `JSONString`, `JSONInt`, `JSONLong`, `JSONDecimal` or `JSONBoolean`\n- `JSONArray`\n- `JSONObject`\n- `JSONStructure`: `JSONArray` or `JSONObject`\n- `JSONValue`: any of the above types\n\nThe usage of `JSONRef` is best explained be example:\n```kotlin\n    val json = JSON.parseObject(\"file.json\")\n    val ref = JSONRef(json)\n```\nThe value `ref` will be of type `JSONRef\u003cJSONObject\u003e`; it will be a reference to the root of the object tree.\n\nThis may be simplified by the use of the `ref()` extension function:\n```kotlin\n    val jsonRef = JSON.parseObject(\"file.json\").ref()\n```\nThe result is the same; the only difference is that the syntax may be easier to read.\n\n`JSONRef\u003cJ\u003e` exposes three properties:\n\n| Name      | Type          | Description                              |\n|-----------|---------------|------------------------------------------|\n| `base`    | `JSONValue`   | The base JSON value                      |\n| `pointer` | `JSONPointer` | The `JSONPointer` to the referenced node |\n| `node`    | `J`           | The node (`J` a subtype of `JSONValue?`) |\n\n\n#### Navigation\n\n`JSONRef` is ideally suited to the task of navigating a JSON structure.\nThe `JSONRef` object itself is immutable, so to navigate to a nested part of a structure, the `child` operation creates\na new `JSONRef` pointing to the appropriate location in the structure.\n\nTo navigate to the `id` property of the object in the above example, expecting it to be a string:\n```kotlin\n    val idRef = ref.child\u003cJSONString\u003e(\"id\")\n    val id = idRef.node\n```\n`idRef` will be of type `JSONRef\u003cJSONString\u003e`, and `id` will be of type `JSONString`.\nThe function will throw an exception if the property `id` is missing, is null or is not a `JSONString`\n\nNow imagine that the object contains a property named `address`, which is an array of address line strings:\n```kotlin\n    val addressRef = ref.child\u003cJSONArray\u003e(\"address\")\n    val line0Ref = addressRef.child\u003cJSONString\u003e(0)\n    val line0 = line0Ref.node\n```\n`addressRef` will be of type `JSONRef\u003cJSONArray\u003e`, `line0Ref` will be of type `JSONRef\u003cJSONString\u003e` and `line0` will be\nof type `JSONString`.\n\nTo navigate to the parent node:\n```kotlin\n   val parentRef = addressRef.parent\u003cJSONObject\u003e()\n```\nIn this example, `parentRef` will now be identical to the original `ref`.\n\n\n#### Iteration\n\nTo iterate over the address lines from the example above:\n```kotlin\n    addressRef.forEach\u003cJSONString\u003e {\n        // within this code, \"this\" is a JSONRef\u003cJSONString\u003e, and \"it\" is an Int (the index)\n        println(\"Address line ${it + 1}: ${node.value}\")\n    }\n```\n\nOr over the properties of an object:\n```kotlin\n    ref.forEachKey\u003cJSONValue\u003e {\n        // within this code, \"this\" is a JSONRef\u003cJSONValue\u003e, and \"it\" is a String (the object key / property name)\n    }\n```\nThis also illustrates the use of `JSONValue` as the parameterised type \u0026ndash; this is saying that the value may be any\nnon-null `JSONValue`, to allow for the case where properties are of different types.\nWhen using a `JSONRef\u003cJSONValue\u003e`, the `isRef()` function tests whether the reference is to a node of a specific type:\n```kotlin\n    if (genericRef.isRef\u003cJSONBoolean\u003e()) {\n        doSomething(genericRef)\n    }\n```\nand the `asRef()` function converts to a specified type, throwing an exception if the type is incorrect:\n```kotlin\n    val stringRef = genericRef.asRef\u003cJSONString\u003e()\n```\n\n\n#### Optional Properties\n\nThere are a number of functions provided as extension functions on `JSONRef\u003cJSONObject\u003e` to simplify access to optional\nproperties of the object:\n\n- `optionalString(name)`: returns the `String` value of the named property, or `null` if it is not present\n- `optionalInt(name)`: returns the `Int` value of the named property, or `null` if it is not present\n- `optionalLong(name)`: returns the `Long` value of the named property, or `null` if it is not present\n- `optionalDecimal(name)`: returns the `BigDecimal` value of the named property, or `null` if it is not present\n- `optionalBoolean(name)`: returns the `Boolean` value of the named property, or `null` if it is not present\n\nIn all cases, if the property is not of the required type, an exception is thrown detailing the expected type, the\nactual value and the location in the structure, in `JSONPointer` form.\n\nWhen the optional property is a nested sub-structure, the `optionalChild()` function may be used:\n```kotlin\n    ref.optionalChild\u003cJsonObject\u003e(\"address\")?.apply {\n        // within this code, \"this\" is a JSONRef\u003cJSONObject\u003e\n    }\n```\nAs with the other optional functions, if the property is present but of the wrong type, a detailed exception is thrown.\n\nAnd to execute a block of code conditionally, depending on the presence of an optional child:\n```kotlin\n    ref.withOptionalChild\u003cJSONString\u003e(\"name\") {\n        // within this code, \"this\" is a JSONRef\u003cJSONString\u003e, and \"it\" is the JSONString\n    }\n```\nAnd again, if the property is present but of the wrong type, a detailed exception is thrown.\n\n## Dependency Specification\n\nThe latest version of the library is 8.8, and it may be obtained from the Maven Central repository.\n\n### Maven\n```xml\n    \u003cdependency\u003e\n      \u003cgroupId\u003eio.kjson\u003c/groupId\u003e\n      \u003cartifactId\u003ekjson-pointer\u003c/artifactId\u003e\n      \u003cversion\u003e8.8\u003c/version\u003e\n    \u003c/dependency\u003e\n```\n### Gradle\n```groovy\n    implementation 'io.kjson:kjson-pointer:8.8'\n```\n### Gradle (kts)\n```kotlin\n    implementation(\"io.kjson:kjson-pointer:8.8\")\n```\n\nPeter Wall\n\n2025-02-06\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpwall567%2Fkjson-pointer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpwall567%2Fkjson-pointer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpwall567%2Fkjson-pointer/lists"}