diff --git a/EliteAPI.Tests/Flattening.cs b/EliteAPI.Tests/Flattening.cs index 9c24ff05..d472f880 100644 --- a/EliteAPI.Tests/Flattening.cs +++ b/EliteAPI.Tests/Flattening.cs @@ -1,4 +1,5 @@ using FluentAssertions; +using Newtonsoft.Json.Linq; namespace EliteAPI.Tests; @@ -50,7 +51,7 @@ public void SimpleArray() paths.Should().BeEquivalentTo(expected); } - + [Test] public void ArrayWithObject() { @@ -506,22 +507,6 @@ public void VeryLongString() paths.Should().BeEquivalentTo(expected); } - [Test] - public void NullInArray() - { - var json = """{ "items": [1, null, 3] }"""; - var paths = FlattenJson(json); - - var expected = new[] - { - new JsonPath("items[0]", 1, JsonType.Number), - new JsonPath("items[1]", 3, JsonType.Number), - new JsonPath("items.Length", 3, JsonType.Number) - }; - - paths.Should().BeEquivalentTo(expected); - } - [Test] public void NullInNestedObject() { @@ -537,9 +522,22 @@ public void NullInNestedObject() paths.Should().BeEquivalentTo(expected); } - private List FlattenJson(string json) + private static List FlattenJson(string json) { // TODO: call flattening function - return []; + // arrays need Length + // key + localisation + // controls mapping + + List temp = []; + var jToken = JToken.Parse(json); + foreach (var jValue in jToken.GetLeafValues()) + { + var jpath = jValue.ToCustomJsonPath(); + // Skips values that are null + if (!(string.IsNullOrWhiteSpace(jpath.Path) || string.IsNullOrWhiteSpace(jpath.Path))) temp.Add(jpath); + } + + return temp; } -} \ No newline at end of file +} diff --git a/EliteAPI/Class1.cs b/EliteAPI/Class1.cs new file mode 100644 index 00000000..ee91faaa --- /dev/null +++ b/EliteAPI/Class1.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json.Linq; + +namespace EliteAPI; + +public class EliteApi +{ + public static void Main() + { + var file = File.ReadAllLines("C:\\Users\\thevi\\Documents\\WORK_SPACE\\EliteAPI\\EliteAPI.Tests\\TestFiles\\Journals\\Journal.2000-01-01T100000.01.log"); + + } +} diff --git a/EliteAPI/EliteAPI.csproj b/EliteAPI/EliteAPI.csproj index aa94bbf6..d2f5dc30 100644 --- a/EliteAPI/EliteAPI.csproj +++ b/EliteAPI/EliteAPI.csproj @@ -7,4 +7,8 @@ Exe + + + + diff --git a/EliteAPI/JsonExtensions.cs b/EliteAPI/JsonExtensions.cs new file mode 100644 index 00000000..74ff494a --- /dev/null +++ b/EliteAPI/JsonExtensions.cs @@ -0,0 +1,136 @@ +using System.Text.Json; +using Newtonsoft; +using Newtonsoft.Json.Linq; + +namespace EliteAPI; + +public static class JExtensions +{ + public static IEnumerable GetLeafValues(this JToken jToken) + { + if (jToken is JValue jvalue) + { + yield return jvalue; + } + else if (jToken is JArray jArray) + { + foreach (var result in GetLeafValuesFromJArray(jArray)) + { + yield return result; + } + + // yield return GetLeafValues(JToken.Parse($"{{ {jArray.Path.Replace(".", "")}: {{ 'Length': {jArray.Count} }} }}")).First(); + yield return GetLeafValuesFromJProperty(new JProperty($"{jArray.Path}.Length", jArray.Count)).First(); + + } + else if (jToken is JProperty jProperty) + { + foreach (var result in GetLeafValuesFromJProperty(jProperty)) + { + yield return result; + } + } + else if (jToken is JObject jObject) + { + foreach (var result in GetLeafValuesFromJObject(jObject)) + { + yield return result; + } + } + } + + + // JSONToken -> JsonPath + public static JsonPath ToCustomJsonPath(this JValue jValue) + { + switch (jValue.Type) + { + case JTokenType.Integer: + return new JsonPath + { + Path = NormalizePath(jValue.Path), + Value = Convert.ToInt32(jValue.Value), + Type = JsonType.Number + }; + case JTokenType.Float: + return new JsonPath + { + Path = NormalizePath(jValue.Path), + Value = Convert.ToDecimal(jValue.Value), + Type = JsonType.Decimal + }; + + case JTokenType.Uri: + case JTokenType.Guid: + case JTokenType.String: + return new JsonPath + { + Path = NormalizePath(jValue.Path), + Value = Convert.ToString(jValue.Value), + Type = JsonType.String + }; + case JTokenType.Boolean: + return new JsonPath + { + Path = NormalizePath(jValue.Path), + Value = Convert.ToBoolean(jValue.Value), + Type = JsonType.Boolean + }; + case JTokenType.Date: + return new JsonPath + { + Path = NormalizePath(jValue.Path), + Value = Convert.ToDateTime(jValue.Value), + Type = JsonType.DateTime + }; + default: + return new JsonPath + { + Path = "", + Value = "", + Type = JsonType.String + }; + } + } + + #region Helpers + + static string NormalizePath(string rawPath) + { + if (rawPath.StartsWith("['") && rawPath.EndsWith("']")) + return rawPath.Substring(2, rawPath.Length - 4); + return rawPath; + } + + static IEnumerable GetLeafValuesFromJArray(JArray jArray) + { + for (var i = 0; i < jArray.Count; i++) + { + foreach (var result in GetLeafValues(jArray[i])) + { + yield return result; + } + } + } + + static IEnumerable GetLeafValuesFromJProperty(JProperty jProperty) + { + foreach (var result in GetLeafValues(jProperty.Value)) + { + yield return result; + } + } + + static IEnumerable GetLeafValuesFromJObject(JObject jObject) + { + foreach (var jToken in jObject.Children()) + { + foreach (var result in GetLeafValues(jToken)) + { + yield return result; + } + } + } + + #endregion +} diff --git a/EliteAPI/JsonPath.cs b/EliteAPI/JsonPath.cs index 3e214992..8f21af29 100644 --- a/EliteAPI/JsonPath.cs +++ b/EliteAPI/JsonPath.cs @@ -2,11 +2,14 @@ namespace EliteAPI; public readonly struct JsonPath(string path, dynamic value, JsonType type) { + public string Path { get; init; } = path; public dynamic Value { get; init; } = value; public JsonType Type { get; init; } = type; + + } public enum JsonType