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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions