From Legacy XML to Modern JSON
How to Extract Deeply Nested Values with JSONPath
A practical education post showing how JSONPath helps teams query deeply nested converted payloads without losing the thread.
The payload is valid. The conversion worked. The response is even pretty-printed. And still you cannot find the one field you need without scrolling past a forest of objects. That is the moment JSONPath starts to feel less like a niche syntax and more like a survival skill.
Up to this point, the series has moved from old XML weight to readable XML and then into JSON syntax errors. Now we reach the part that rewards all that cleanup: once the data is valid, you can finally ask sharper questions about what it actually contains.
The problem is depth. Converted payloads grow quickly. A small XML document can turn into nested JSON with repeated arrays, optional objects, and new wrapper keys introduced by the transformation layer. Reading is possible. Re-reading is exhausting.
That is why JSONPath matters.
Why JSONPath becomes useful after migration work
A lot of JSONPath tutorials start with syntax. Dots, wildcards, filters, recursive descent. Those mechanics matter, but they land better when attached to a real need. In migration work, that need is simple: find the same nested value repeatedly without manually navigating the whole payload every time.
Maybe you need the supplier code buried under a list of fulfillment nodes.
Maybe you need the third price adjustment from a converted invoice.
Maybe you need to confirm which optional field disappeared after a transform step.
Without a query language, each check becomes a fresh scavenger hunt. With JSONPath, the hunt becomes a repeatable question.
Nested JSON is readable, but not always searchable by eye
Formatting helps you see structure, but it does not remove complexity. A well-indented payload can still be too wide and deep to inspect efficiently, especially when similar keys repeat under different parents.
That is a common side effect of XML-to-JSON work. The new format is friendlier, but the underlying domain complexity remains. A purchase order still has headers, lines, adjustments, taxes, vendor metadata, and fulfillment details. The payload is easier to read, yet not always easy to interrogate.
This is where JSON Path Tester becomes practical. Instead of re-reading the document to answer the same question, you write the question down as a path and let the result surface itself.
Start with the question, not the syntax
The easiest way to make JSONPath useful is to lead with intent. Ask what you need before you decide how to write the query.
Do I need every sku value from every line item?
Do I need the final computed total?
Do I need every error message under a validation branch?
Do I need all discount codes applied to one order?
Once the question is narrow, the path often becomes manageable.
$.order.items[*].sku
$.pricing.total
$.validation.errors[*].message
The simplicity matters. Many teams avoid JSONPath because they imagine it as a specialized skill for data wranglers. In practice, the most useful queries are often short and repeatable.
JSONPath helps when comparison tells you where to look
One of the nicest pairings in this workflow is JSONPath plus comparison. After you convert data and validate syntax, you often compare two payloads to see what changed. Once the changed branch becomes visible, JSONPath gives you a reliable way to keep querying that branch across different runs or environments.
That combination matters because a single migration rarely ends in one test. Teams inspect staging, preview, local fixtures, and sometimes partner-supplied samples. Writing the path once and reusing it prevents the same cognitive work from repeating across every sample.
It also improves communication. “The missing value is under $.order.items[*].pricing.discount.amount” is much more helpful than “It’s somewhere inside the items section.”
A practical example from converted supplier data
Imagine an XML feed converted into JSON for an internal inventory dashboard. The team keeps missing a supplier status flag because it lives several layers deep:
{
"supplier": {
"catalog": {
"products": [
{
"sku": "BX-19",
"availability": {
"warehouse": {
"status": "backorder"
}
}
}
]
}
}
}
You could scroll to it every time. Or you could ask for it directly:
$.supplier.catalog.products[*].availability.warehouse.status
That is not flashy. It is just useful. And usefulness is exactly why JSONPath survives beyond tutorials.
Querying reduces review fatigue
Payload review gets tiring because your eyes keep doing expensive navigation. By the fifth sample, even careful engineers begin to skim. JSONPath reduces that fatigue by turning repeated inspection into extraction instead of exploration.
That makes code review better too. If a transform change is supposed to preserve three fields, reviewers can query those three fields quickly instead of trusting a general impression of the output. Precision improves without making the workflow slower.
This is especially valuable in CI-heavy teams, where converted data often shows up in fixtures, generated artifacts, and test outputs. A queryable inspection step is easier to sustain than repeated manual scrolling.
The path from XML cleanup to CI confidence
At this point the story has moved a long way. We started with a legacy XML API, made the source readable with an XML formatter, protected the transformed output from JSON syntax errors, and now used JSONPath to make deep structures easier to inspect.
The natural next question is operational: where does this help a team day to day?
One answer lives in CI workflows and configuration review. Once teams trust conversion and validation habits, they can use the same approach on YAML-driven automation. The destination is not only cleaner payloads. It is cleaner release workflows too.
That is what the final post covers. Using YAML to JSON Conversion in GitHub Actions and CI turns this whole sequence into something teams can apply to workflows they touch every week.