Skip to content

Q: How to use constant in json path? #1070

@anatoly-spb

Description

@anatoly-spb

Hello!

I want to concatanate several json paths separated by a string constant with the concat function:

      String json =
      """
      {
        "one": "one",
        "two": "two"
      }
      """;
        ReadContext readContext =
            JsonPath.using(
                    Configuration.builder()
                        .jsonProvider(new JacksonJsonNodeJsonProvider())
                        .mappingProvider(new JacksonMappingProvider())
                        .build())
                .parse(json);
      Object result = readContext.read("concat($.one, \"-\", $.two)");
      assertThat(result).isEqualTo("one-two");

but instead of "one-two" there is the "one"-"two" in result.

How to fix it to get correct result?

It seems to me it is because of com.fasterxml.jackson.databind.node.TextNode.toString:

  public String toString() {
    return InternalNodeMapper.nodeToString(this);
  }

which used in the Parameter.consume where the value argument is com.fasterxml.jackson.databind.node.TextNode:

  public static void consume(Class expectedType, EvaluationContext ctx, Collection collection, Object value) {
    if (ctx.configuration().jsonProvider().isArray(value)) {
      for(Object o : ctx.configuration().jsonProvider().toIterable(value)) {
        if (o != null && expectedType.isAssignableFrom(o.getClass())) {
          collection.add(o);
        } else if (o != null && expectedType == String.class) {
          collection.add(o.toString()); // here is o.toString() returns ""-"", instead of "-"
        }
      }
    } else if (value != null && expectedType.isAssignableFrom(value.getClass())) {
      collection.add(value);
    } else if (value != null && expectedType == String.class) {
      collection.add(value.toString());
    }

  }

JsonLateBindingValue.getValue calls JacksonJsonNodeJsonProvider.parse:

  public Object get() {
    return this.jsonProvider.parse(this.jsonParameter.getJson());
  }

JacksonJsonNodeJsonProvider.parse returns TextNode:

  public Object parse(String json) throws InvalidJsonException {
    try {
      return this.objectMapper.readTree(json);
    } catch (IOException e) {
      throw new InvalidJsonException(e, json);
    }
  }

I use json-path 2.10.0 based on Jackson:

    <dependency>
      <groupId>com.jayway.jsonpath</groupId>
      <artifactId>json-path</artifactId>
      <version>2.10.0</version>
    </dependency>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions