JsonPathUtilities
Utilities to work with JSON paths.
using Newtonsoft.Json.Serialization;
using NJsonSchema.Infrastructure;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace NJsonSchema
{
public static class JsonPathUtilities
{
private static readonly Lazy<CamelCasePropertyNamesContractResolver> CamelCaseResolverLazy = new Lazy<CamelCasePropertyNamesContractResolver>();
public static string GetPropertyName(PropertyInfo property, PropertyNameHandling propertyNameHandling)
{
switch (propertyNameHandling) {
case PropertyNameHandling.Default:
return ReflectionCache.GetProperties(property.DeclaringType).First((ReflectionCache.Property p) => p.PropertyInfo.Name == property.Name).GetName();
case PropertyNameHandling.CamelCase:
return CamelCaseResolverLazy.Value.GetResolvedPropertyName(property.Name);
default:
throw new NotSupportedException($"""{propertyNameHandling}""");
}
}
public static string GetJsonPath(object root, object objectToSearch, ISchemaDefinitionAppender schemaDefinitionAppender = null)
{
string jsonPath = GetJsonPath(root, objectToSearch, "#", new HashSet<object>());
if (jsonPath == null) {
if (schemaDefinitionAppender != null && objectToSearch is JsonSchema4) {
schemaDefinitionAppender.Append(root, (JsonSchema4)objectToSearch);
return GetJsonPath(root, objectToSearch, schemaDefinitionAppender);
}
throw new InvalidOperationException("Could not find the JSON path of a child object.");
}
return jsonPath;
}
private static string GetJsonPath(object obj, object objectToSearch, string basePath, HashSet<object> checkedObjects)
{
if (obj == null || obj is string || checkedObjects.Contains(obj))
return null;
if (obj == objectToSearch)
return basePath;
checkedObjects.Add(obj);
if (obj is IDictionary) {
foreach (object key in ((IDictionary)obj).Keys) {
string jsonPath = GetJsonPath(((IDictionary)obj)[key], objectToSearch, basePath + "/" + key, checkedObjects);
if (jsonPath != null)
return jsonPath;
}
} else if (obj is IEnumerable) {
int num = 0;
foreach (object item in (IEnumerable)obj) {
string jsonPath2 = GetJsonPath(item, objectToSearch, basePath + "/" + num, checkedObjects);
if (jsonPath2 != null)
return jsonPath2;
num++;
}
} else {
foreach (ReflectionCache.Property item2 in from p in ReflectionCache.GetProperties(obj.GetType())
where p.CustomAttributes.JsonIgnoreAttribute == null
select p) {
object value = ReflectionExtensions.GetValue(item2.PropertyInfo, obj);
if (value != null) {
string name = item2.GetName();
string jsonPath3 = GetJsonPath(value, objectToSearch, basePath + "/" + name, checkedObjects);
if (jsonPath3 != null)
return jsonPath3;
}
}
}
return null;
}
}
}