Skip to content

Usage Overview

kPointer is layered. Pick the layer that matches what you have:

graph TD
  core["kpointer-core<br/>(KPointer: parse & manipulate pointer strings)"]
  adapter["kpointer-adapter<br/>(KpaStruct / KpaList / KpaPrimitive + get / mutate)"]
  kxs["kpointer-kxs<br/>(kotlinx.serialization)"]
  yamlkt["kpointer-yamlkt<br/>(YamlKt)"]
  ksoup["kpointer-ksoup<br/>(KSoup HTML/XML, read-only)"]

  adapter --> core
  kxs --> adapter
  yamlkt --> adapter
  ksoup --> adapter
  • You only have pointer strings to parse, compare, or transform → use kpointer-core directly.
  • You have a document and want to read or mutate it by pointer → use the adapter module for your representation: JSON, YAML, or XML/HTML.
  • You have a different tree type and want pointer support for it → implement a custom adapter on top of kpointer-adapter.

Each adapter module re-exports kpointer-adapter and kpointer-core as transitive api dependencies, so declaring the one adapter artifact is enough.

Adding a dependency

kPointer is published on Maven Central under the com.commonsware.kpointer group. Declare only the module you need; the lower layers come transitively.

[versions]
kpointer = "0.2.0"

[libraries]
kpointer-kxs = { module = "com.commonsware.kpointer:kpointer-kxs", version.ref = "kpointer" }
[versions]
kpointer = "0.2.0"

[libraries]
kpointer-yamlkt = { module = "com.commonsware.kpointer:kpointer-yamlkt", version.ref = "kpointer" }
[versions]
kpointer = "0.2.0"

[libraries]
kpointer-ksoup = { module = "com.commonsware.kpointer:kpointer-ksoup", version.ref = "kpointer" }
[versions]
kpointer = "0.2.0"

[libraries]
kpointer-core = { module = "com.commonsware.kpointer:kpointer-core", version.ref = "kpointer" }

Then reference it from your module:

dependencies {
    implementation(libs.kpointer.kxs) // or .yamlkt / .ksoup / .core
}

Two operations, everywhere

Whichever document module you use, the shape of the API is the same:

  • Read with the [] operator or an elementAt/typed-accessor extension, passing a KPointer or a plain pointer string. An absent path yields null.
  • Mutate with a mutate { … } block that returns a new document — the original is never changed. Inside the block, "/path" to value sets and remove("/path") deletes.
// read
val name = document.elementAt("/user/name")

// mutate (returns a new document; `document` is untouched)
val updated = document.mutate {
    "/user/name" to "Alice"
    remove("/user/deprecated")
}

The per-format pages cover the exact receiver types, typed accessors, and format-specific behavior. See the Document Model page for a tour of KpaStruct, KpaList, and KpaPrimitive — the adapter-neutral types that every read operation returns.