JSON Transformer Skill
Transform, manipulate, and analyze JSON data structures with advanced operations.
Instructions
You are a JSON transformation expert. When invoked:
-
Parse and Validate JSON:
- Parse JSON from files, strings, or APIs
- Validate JSON structure and schema
- Handle malformed JSON gracefully
- Pretty-print and format JSON
- Detect and fix common JSON issues
-
Transform Data Structures:
- Reshape nested objects and arrays
- Flatten and unflatten structures
- Extract specific paths (JSONPath, JMESPath)
- Merge and combine JSON documents
- Filter and map data
-
Advanced Operations:
- Convert between JSON and other formats (CSV, YAML, XML)
- Apply transformations (jq-style operations)
- Query and search JSON data
- Diff and compare JSON documents
- Generate JSON from schemas
-
Data Manipulation:
- Add, update, delete properties
- Rename keys
- Convert data types
- Sort and deduplicate
- Calculate aggregate values
Usage Examples
@json-transformer data.json
@json-transformer --flatten
@json-transformer --path "users[*].email"
@json-transformer --merge file1.json file2.json
@json-transformer --to-csv data.json
@json-transformer --validate schema.json
Basic JSON Operations
Parsing and Writing
Python
import json
# Parse JSON string
data = json.loads('{"name": "John", "age": 30}')
# Parse from file
with open('data.json', 'r') as f:
data = json.load(f)
# Write JSON to file
with open('output.json', 'w') as f:
json.dump(data, f, indent=2)
# Pretty print
print(json.dumps(data, indent=2, sort_keys=True))
# Compact output
compact = json.dumps(data, separators=(',', ':'))
# Handle special types
from datetime import datetime
import decimal
def json_encoder(obj):
if isinstance(obj, datetime):
return obj.isoformat()
if isinstance(obj, decimal.Decimal):
return float(obj)
raise TypeError(f"Type {type(obj)} not serializable")
json.dumps(data, default=json_encoder)
JavaScript
// Parse JSON string
const data = JSON.parse('{"name": "John", "age": 30}');
// Parse from file (Node.js)
const fs = require('fs');
const data = JSON.parse(fs.readFileSync('data.json', 'utf8'));
// Write JSON to file
fs.writeFileSync('output.json', JSON.stringify(data, null, 2));
// Pretty print
console.log(JSON.stringify(data, null, 2));
// Custom serialization
const json = JSON.stringify(data, (key, value) => {
if (value instanceof Date) {
return value.toISOString();
}
return value;
}, 2);
jq (Command Line)
# Pretty print
cat data.json | jq '.'
# Compact output
cat data.json | jq -c '.'
# Sort keys
cat data.json | jq -S '.'
# Read from file, write to file
jq '.' input.json > output.json
Validation
Python (jsonschema)
from jsonschema import validate, ValidationError
# Define schema
schema = {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "number", "minimum": 0},
"email": {"type": "string", "format": "email"}
},
"required": ["name", "email"]
}
# Validate data
data = {"name": "John", "email": "john@example.com", "age": 30}
try:
validate(instance=data, schema=schema)
print("Valid JSON")
except ValidationError as e:
print(f"Invalid: {e.message}")
# Validate against JSON Schema draft
from jsonschema import Draft7Validator
validator = Draft7Validator(schema)
errors = list(validator.iter_errors(data))
for error in errors:
print(f"Error at {'.'.join(str(p) for p in error.path)}: {error.message}")
JavaScript (ajv)
const Ajv = require('ajv');
const ajv = new Ajv();
const schema = {
type: 'object',
properties: {
name: { type: 'string' },
age: { type: 'number', minimum: 0 },
email: { type: 'string', format: 'email' }
},
required: ['name', 'email']
};
const validate = ajv.compile(schema);
const data = { name: 'John', email: 'john@example.com', age: 30 };
if (validate(data)) {
console.log('Valid JSON');
} else {
console.log('Invalid:', validate.errors);
}
Data Extraction and Querying
JSONPath Queries
Python (jsonpath-ng)
from jsonpath_ng import jsonpath, parse
data = {
"users": [
{"name": "John", "age": 30, "email": "john@example.com"},
{"name": "Jane", "age": 25, "email": "jane@example.com"}
]
}
# Extract all user names
jsonpath_expr = parse('users[*].name')
names = [match.value for match in jsonpath_expr.find(data)]
# Result: ['John', 'Jane']
# Extract emails of users over 25
jsonpath_expr = parse('users[?(@.age > 25)].email')
emails = [match.value for match in jsonpath_expr.find(data)]
# Nested extraction
data = {
"company": {
"departments": [
{
"name": "Engineering",
"employees": [
{"name": "Alice", "salary": 100000},
{"name": "Bob", "salary": 90000}
]
}
]
}
}
jsonpath_expr = parse('company.departments[*].employees[*].name')
names = [match.value for match in jsonpath_expr.find(data)]
jq
# Extract field
echo '{"name": "John", "age": 30}' | jq '.name'
# Extract from array
echo '[{"name": "John"}, {"name": "Jane"}]' | jq '.[].name'
# Filter array
echo '[{"name": "John", "age": 30}, {"name": "Jane", "age": 25}]' | \
jq '.[] | select(.age > 25)'
# Extract nested fields
cat data.json | jq '.users[].email'
# Multiple fields
cat data.json | jq '.users[] | {name: .name, email: .email}'
# Conditional extraction
cat data.json | jq '.users[] | select(.age > 25) | .email'
JMESPath Queries
Python (jmespath)
import jmespath
data = {
"users": [
{"name": "John", "age": 30, "tags": ["admin", "developer"]},
{"name": "Jane", "age": 25, "tags": ["developer"]},
{"name": "Bob", "age": 35, "tags": ["manager"]}
]
}
# Simple extraction
names = jmespath.search('users[*].name', data)
# Result: ['John', 'Jane', 'Bob']
# Filtering
admins = jmespath.search('users[?contains(tags, `admin`)]', data)
# Multiple conditions
senior_devs = jmespath.search(
'users[?age > `28` && contains(tags, `developer`)]',
data
)
# Projections
result = jmespath.search('users[*].{name: name, age: age}', data)
# Nested queries
data = {
"departments": [
{
"name": "Engineering",
"employees": [
{"name": "Alice", "skills": ["Python", "Go"]},
{"name": "Bob", "skills": ["JavaScript", "Python"]}
]
}
]
}
python_devs = jmespath.search(
'departments[*].employees[?contains(skills, `Python`)].name',
data
)
Data Transformation
Flattening Nested JSON
Python
def flatten_json(nested_json, parent_key='', sep='.'):
"""
Flatten nested JSON structure
"""
items = []
for key, value in nested_json.items():
new_key = f"{parent_key}{sep}{key}" if parent_key else key
if isinstance(value, dict):
items.extend(flatten_json(value, new_key, sep=sep).items())
elif isinstance(value, list):
for i, item in enumerate(value):
if isinstance(item, dict):
items.extend(flatten_json(item, f"{new_key}[{i}]", sep=sep).items())
else:
items.append((f"{new_key}[{i}]", item))
else:
items.append((new_key, value))
return dict(items)
# Example
nested = {
"user": {
"name": "John",
"address": {
"city": "New York",
"zip": "10001"
},
"tags": ["admin", "developer"]
}
}
flat = flatten_json(nested)
# Result: {
# 'user.name': 'John',
# 'user.address.city': 'New York',
# 'user.address.zip': '10001',
# 'user.tags[0]': 'admin',
# 'user.tags[1]': 'devel