Git Product home page Git Product logo

kotlinx-serialization-jsonpath's Introduction

Module KotlinX Serialization JsonPath

Maven Central Latest snapshot

JsonPath offers a simple DSL to work with JsonElement from Kotlinx Serialization Json, this allows you to easily work with JSON in Kotlin in a typed manner. Simply add the following dependency as implementation in the build.gradle dependencies` block.

dependencies {
  implementation("io.github.nomisrev:kotlinx-serialization-jsonpath:0.2.0")
}

Let's dive right in with following JSON_STRING as input JsonElement that models a simple company.

{
  "name": "Arrow",
  "address": {
    "city": "Functional Town",
    "street": {
      "number": 1337,
      "name": "Functional street"
    }
  },
  "employees": [
    {
      "name": "John",
      "lastName": "doe"
    },
    {
      "name": "Jane",
      "lastName": "doe"
    }
  ]
}

Given this JsonElement we can select the name from the JsonElement. This gives us an Optional from the root JsonElement to the name property with type String. We can then use this JsonPath to modify the original JsonElement's name property, this gives us back a new JsonElement with the name modified according to the passed String::uppercase function.

  val json: JsonElement = Json.decodeFromString(JSON_STRING)
  val name: Optional<JsonElement, String> = JsonPath.select("name").string
  println(name.modify(json, String::uppercase))

You can get the full code here.

{"name":"ARROW","address":{"city":"Functional Town","street":{"number":1337,"name":"Functional street"}},"employees":[{"name":"John","lastName":"doe"},{"name":"Jane","lastName":"doe"}]}

As we've seen above we can select a property from a JsonObject, but what if we want to access deeply nested properties in our JsonElement? For that we can use path which allows you to select deeply nested properties using the dot (.) notation you might know from Javascript.

Below we select the address JsonObject, and from the address JsonObject we then select the street JsonObject, to then finally select the name of the street.

This again returns us an Optional<JsonElement, String>, which we use to modify the address.street.name. We then also extract the value using getOrNull which returns us the desired path in our JsonElement, or it returns null if the desired path is not available in our JsonElement.

  val json: JsonElement = Json.decodeFromString(JSON_STRING)
  val name: Optional<JsonElement, String> = JsonPath.path("address.street.name").string
  val res: JsonElement = name.modify(json, String::uppercase).also(::println)
  name.getOrNull(res)?.also(::println)

You can get the full code here.

{"name":"Arrow","address":{"city":"Functional Town","street":{"number":1337,"name":"FUNCTIONAL STREET"}},"employees":[{"name":"John","lastName":"doe"},{"name":"Jane","lastName":"doe"}]}
FUNCTIONAL STREET

In the previous examples we've seen how we can select properties out of JsonObject, but when working with JsonElement we also often have to deal with JsonArray that can contain many JsonElement. For these use-cases we can use every, which focuses into every JsonElement in our JsonArray.

In the example below we select the employees JsonArray, and then we select every JsonElement in the JsonArray. We then select the name out of every JsonElement.

Instead of Optional<JsonElement, String> it now returns Traversal<JsonElement, String>, since we selected many properties instead of a single property.

Just like before we can apply a function to it using modify, and we can also extract every property using getAll. This returns us an emptyList() when no values were found along the path, or all found values inside a List.

  val json: JsonElement = Json.decodeFromString(JSON_STRING)
  val employeesName: Traversal<JsonElement, String> = JsonPath.select("employees").every.select("name").string
  val res: JsonElement = employeesName.modify(json, String::uppercase).also(::println)
  employeesName.getAll(res).also(::println)

You can get the full code here.

{"name":"Arrow","address":{"city":"Functional Town","street":{"number":1337,"name":"Functional street"}},"employees":[{"name":"JOHN","lastName":"doe"},{"name":"JANE","lastName":"doe"}]}
[JOHN, JANE]

Alternatively we can also use the pathEvery function to select every JsonElement in our JsonArray. Like for path we can also use the dot (.) notation to select deeply nested properties. On the other hand, the star (*) notation allow us to select every JsonElement in our JsonArray.

Like before, below we select the employees JsonArray, and then we select every JsonElement in the JsonArray. We then select the name out of every JsonElement.

Again, instead of Optional<JsonElement, String> it now returns Traversal<JsonElement, String>, since we selected many properties instead of a single property.

You can then, apply a function to it using modify like before.

  val json: JsonElement = Json.decodeFromString(JSON_STRING)
  val employeesName: Traversal<JsonElement, String> = JsonPath.pathEvery("employees.*.name").string
  val res: JsonElement = employeesName.modify(json, String::uppercase).also(::println)
  employeesName.getAll(res).also(::println)

You can get the full code here.

{"name":"Arrow","address":{"city":"Functional Town","street":{"number":1337,"name":"Functional street"}},"employees":[{"name":"JOHN","lastName":"doe"},{"name":"JANE","lastName":"doe"}]}
[JOHN, JANE]

kotlinx-serialization-jsonpath's People

Contributors

gosunet avatar nomisrev avatar renovate[bot] avatar serras avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

serras gosunet

kotlinx-serialization-jsonpath's Issues

Recursive descent is not supported

The recursive descent operator does not appear to be implemented.

For example, $..name should find $.name, but also $.children[0].name, $.children.children.children[0].name, ...

In test case form:

@Test
fun recursiveDescentTest() {
    val obj = buildJsonObject {
        put("name", "Name #1")
        put("addr", "Street 1")
        putJsonArray("children") {
            addJsonObject {
                put("name", "Name #2")
            }
        }
    }
    assertEquals(setOf("Name #1", "Name #2"),
        JsonPath.pathEvery("$..name").getAll(obj).map { it.toString() }.toSet())
}

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

  • Update all dependencies (com.gradle.enterprise, io.gitlab.arturbosch.detekt, io.gitlab.arturbosch.detekt:detekt-gradle-plugin, org.jetbrains.kotlin.plugin.serialization, org.jetbrains.kotlin.multiplatform, org.jetbrains.kotlin:kotlin-gradle-plugin, io.arrow-kt:arrow-optics)
  • Update all dependencies (major) (actions/setup-java, gradle/gradle-build-action, peaceiris/actions-gh-pages)

Detected dependencies

github-actions
.github/workflows/build.yml
  • actions/checkout v4
  • actions/setup-java v4
  • gradle/gradle-build-action v2
.github/workflows/githubpages.yaml
  • actions/checkout v4
  • peaceiris/actions-gh-pages v3
.github/workflows/publish.yml
  • actions/checkout v4
  • actions/setup-java v4
  • gradle/gradle-build-action v2
  • actions/upload-artifact v4
  • gradle/gradle-build-action v2
.github/workflows/pull_request.yaml
  • actions/checkout v4
  • actions/setup-java v3
  • gradle/gradle-build-action v2
gradle
gradle.properties
libs.versions.toml
  • io.arrow-kt:arrow-optics 2.0.0-alpha.1
  • org.jetbrains.dokka:dokka-core 1.9.20
  • io.kotest:kotest-assertions-core 5.9.0
  • io.kotest:kotest-framework-engine 5.9.0
  • io.kotest:kotest-property 5.9.0
  • io.kotest:kotest-runner-junit5 5.9.0
  • io.kotest.extensions:kotest-assertions-arrow 1.4.0
  • org.jetbrains.kotlin:kotlin-gradle-plugin 2.0.0-RC3
  • io.gitlab.arturbosch.detekt:detekt-gradle-plugin 1.23.5
  • org.jetbrains.kotlinx:kotlinx-serialization-json 1.6.3
  • org.jetbrains.kotlinx:kotlinx-knit-test 0.5.0
  • org.jetbrains.kotlin.multiplatform 2.0.0-RC3
  • org.jetbrains.dokka 1.9.20
  • org.jetbrains.kotlinx.kover 0.8.0
  • io.kotest.multiplatform 5.9.0
  • io.gitlab.arturbosch.detekt 1.23.5
  • org.jetbrains.kotlin.plugin.serialization 2.0.0-RC3
  • com.vanniktech.maven.publish 0.28.0
  • org.jetbrains.kotlinx.knit 0.5.0
  • com.diffplug.spotless 6.25.0
settings.gradle.kts
  • com.gradle.enterprise 3.16.2
build.gradle.kts
gradle-wrapper
gradle/wrapper/gradle-wrapper.properties
  • gradle 8.7

  • Check this box to trigger a request for Renovate to run again on this repository

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.