Openai/6937ffdf-2f14-800e-816d-c3a88af3ea11


This conversation was exported from ChatGPT[1]

gpt-5-1 edit

User: I'm using jsonpathng.ext for a project that maps a JSON source to a target. edit

I'm using jsonpath_ng.ext for a project that maps a JSON source to a target. It's largely metadata driven and in many cases a simple jsonpath like "$.email" can map to a target field. In some cases concatenation is required like this; "$.firstName + ' ' + $.lastName". So far, so good. This works.

But; I have an issue whereby source data can have None for an attribute value and this results in the jsonpath parse returning an empty list. I need something similar to this pseudo "($.firstName or ) + ' ' + ($.lastName or )".

Any idea how I can coalesce None to empty string so my concatenation doesn't result in None?

Assistant: Here are three practical, working approaches you can use with jsonpathng.ext to safely coalesce None values to empty st… edit

Here are three practical, working approaches you can use with jsonpath_ng.ext to safely coalesce None values to empty strings during concatenation.

✅ Problem Recap edit

  • You have expressions like:
"$.firstName + ' ' + $.lastName"
  • But if firstName or lastName is None (or missing), jsonpath_ng returns an empty list, causing the expression to fail (or produce None / empty output).
  • You want something like:
($.firstName or '') + ' ' + ($.lastName or '')

🔥 Important Detail edit

jsonpath_ng itself does not support or, boolean logic, or default operators inside expressions.

But you can still safely coalesce values by using Python and jsonpath together.

✅ Solution 1: Use a helper to get a string-safe value edit

This is the recommended and cleanest approach.

Helper: edit
from jsonpath_ng.ext import parse

def extract_safe(data, expr):
    match = parse(expr).find(data)
    if not match:
        return ''           # missing
    value = match[0].value
    return value or ''      # None → '', '' stays ''
Usage: edit
full_name = f"{extract_safe(data, '$.firstName')} {extract_safe(data, '$.lastName')}"

This handles:

  • missing values
  • None
  • empty string
  • type safety

✅ Solution 2: Wrap your jsonpath resolution with .get() logic edit

If your JSON looks like:

data = {
    "firstName": None,
    "lastName": "Ali"
}

You can bypass jsonpath for single-level fields:

full_name = f"{data.get('firstName') or ''} {data.get('lastName') or ''}"

But this only works for simple paths, not nested jsonpath queries.

✅ Solution 3: Pre-clean your source dict recursively edit

If you want jsonpath to always receive "safe" data, convert every None to "":

def coalesce_none(obj):
    if isinstance(obj, dict):
        return {k: coalesce_none(v) for k, v in obj.items()}
    if isinstance(obj, list):
        return [coalesce_none(v) for v in obj]
    return '' if obj is None else obj

Then:

data = coalesce_none(raw_data)

Now jsonpath always gets strings instead of None.

🔥 Solution 4 (Advanced): Extend jsonpath_ng to add a default() function edit

If you need to write expressions like this:

default($.firstName, '') + ' ' + default($.lastName, '')

You can extend the grammar—but this requires custom parser work. If you want, I can generate a full working DefaultFunction extension for jsonpath_ng.ext.

🚀 Which approach should you use? edit

| Approach | Best for | Pros | Cons | | ------------------------ | ------------------------------- | ---------------------- | -------------------------------- | | extract_safe() helper | Concatenation & mapping systems | Simple, explicit, safe | Requires wrapping your paths | | dict.get() | Shallow fields | Very easy | Doesn't support complex jsonpath | | Recursive cleaning | Large JSON transformations | One-time cleanup | Mutates or copies whole JSON | | Custom jsonpath function | Expression-level control | Most flexible | Requires grammar extension |

🎯 Recommended for your mapping engine edit

Use Solution 1 because your mapping is metadata-driven:

first = extract_safe(data, '$.firstName')
last = extract_safe(data, '$.lastName')

target["fullName"] = f"{first} {last}".strip()

If you want, I can also:

  • Add trimming rules
  • Add None → handling for lists
  • Build a more powerful mapping engine wrapper
  • Extend jsonpath to support or or default() syntax

Just tell me!

References edit

  1. "Coalescing None in JSONPath". ChatGPT. Retrieved 2025-12-10.