From 39cfe382d28b776bf03763a19061108ebe959740 Mon Sep 17 00:00:00 2001 From: beggers Date: Wed, 16 Jan 2019 06:42:18 +0100 Subject: [PATCH 01/43] Add equals method --- Examples/DataTransformer.xml | 5 +++++ Examples/Transformer.json | 5 +++++ JUST.net/JsonTransformer.cs | 10 +++++----- JUST.net/ReflectionHelper.cs | 4 ++-- JUST.net/Transformer.cs | 13 ++++++++++++- 5 files changed, 29 insertions(+), 8 deletions(-) diff --git a/Examples/DataTransformer.xml b/Examples/DataTransformer.xml index fefa1a7..fcbaec7 100644 --- a/Examples/DataTransformer.xml +++ b/Examples/DataTransformer.xml @@ -9,6 +9,11 @@ #substring(#valueof($.stringref),8,10) #concat(#valueof($.menu.id.file),#valueof($.menu.value.Window)) + + #equals(#valueof($.menu.id.file),#valueof($.menu.value.Window)) + #equals(#valueof($.menu.id.file),csv) + #equals(Value1,Value2) + #add(#valueof($.numbers[0]),3) #subtract(#valueof($.numbers[4]),#valueof($.numbers[0])) diff --git a/Examples/Transformer.json b/Examples/Transformer.json index 9c81647..67b856e 100644 --- a/Examples/Transformer.json +++ b/Examples/Transformer.json @@ -8,6 +8,11 @@ "arrayelement": "#valueof($.x[0])", "specificelement": "#valueof($.x[1].v.a)" }, + "boolresult": { + "equals": "#equals(#valueof($.menu.id.file),#valueof($.menu.value.Window))", + "equals_val": "#equals(#valueof($.menu.id.file),csv)", + "equals_value": "#equals(Value1,Value2)" + }, "ifconditiontesttrue": "#ifcondition(#valueof($.menu.id.file),csv,#valueof($.menu.value.Window),fail)", "ifconditiontestfalse": "#ifcondition(#valueof($.menu.id.file),xml,#valueof($.menu.value.Window),fail)", "stringresult": { diff --git a/JUST.net/JsonTransformer.cs b/JUST.net/JsonTransformer.cs index 1639d42..b3eeaa4 100644 --- a/JUST.net/JsonTransformer.cs +++ b/JUST.net/JsonTransformer.cs @@ -599,9 +599,9 @@ private static object ParseFunction(string functionString, string inputJson, JAr if (functionName == "currentvalue" || functionName == "currentindex" || functionName == "lastindex" || functionName == "lastvalue") - output = ReflectionHelper.caller(null, "JUST.Transformer", functionName, new object[] { array, currentArrayElement }); + output = ReflectionHelper.InvokeFunction(null, "JUST.Transformer", functionName, new object[] { array, currentArrayElement }); else if (functionName == "currentvalueatpath" || functionName == "lastvalueatpath") - output = ReflectionHelper.caller(null, "JUST.Transformer", functionName, new object[] { array, currentArrayElement, arguments[0] }); + output = ReflectionHelper.InvokeFunction(null, "JUST.Transformer", functionName, new object[] { array, currentArrayElement, arguments[0] }); else if (functionName == "customfunction") output = CallCustomFunction(parameters); else if (Regex.IsMatch(functionName, ReflectionHelper.EXTERNAL_ASSEMBLY_REGEX)){ @@ -615,7 +615,7 @@ private static object ParseFunction(string functionString, string inputJson, JAr { object[] oParams = new object[1]; oParams[0] = parameters; - output = ReflectionHelper.caller(null, "JUST.Transformer", functionName, oParams); + output = ReflectionHelper.InvokeFunction(null, "JUST.Transformer", functionName, oParams); } else { @@ -623,7 +623,7 @@ private static object ParseFunction(string functionString, string inputJson, JAr { parameters[i] = JsonConvert.SerializeObject(currentArrayElement); } - output = ReflectionHelper.caller(null, "JUST.Transformer", functionName, parameters); + output = ReflectionHelper.InvokeFunction(null, "JUST.Transformer", functionName, parameters); } return output; @@ -660,7 +660,7 @@ private static object CallCustomFunction(object[] parameters) className = className + "," + dllName; - return ReflectionHelper.caller(null, className, functionName, customParameters); + return ReflectionHelper.InvokeFunction(null, className, functionName, customParameters); } #endregion diff --git a/JUST.net/ReflectionHelper.cs b/JUST.net/ReflectionHelper.cs index 9dfbf81..5f8f10b 100644 --- a/JUST.net/ReflectionHelper.cs +++ b/JUST.net/ReflectionHelper.cs @@ -12,7 +12,7 @@ internal class ReflectionHelper { internal const string EXTERNAL_ASSEMBLY_REGEX = "([\\w.]+)[:]{2}([\\w.]+)[:]{0,2}([\\w.]*)"; - internal static object caller(Assembly assembly, String myclass, String mymethod, object[] parameters, bool convertParameters = false) + internal static object InvokeFunction(Assembly assembly, String myclass, String mymethod, object[] parameters, bool convertParameters = false) { Type type = assembly?.GetType(myclass) ?? Type.GetType(myclass); MethodInfo methodInfo = type.GetTypeInfo().GetMethod(mymethod); @@ -42,7 +42,7 @@ internal static object CallExternalAssembly(string functionName, object[] parame var assembly = GetAssembly(isAssemblyDefined, assemblyName, namespc, methodName); if (assembly != null) { - return caller(assembly, namespc, methodName, FilterParameters(parameters), true); + return InvokeFunction(assembly, namespc, methodName, FilterParameters(parameters), true); } throw new MissingMethodException((assemblyName != null ? $"{assemblyName}." : string.Empty) + $"{namespc}.{methodName}"); diff --git a/JUST.net/Transformer.cs b/JUST.net/Transformer.cs index 69dcffa..c319402 100644 --- a/JUST.net/Transformer.cs +++ b/JUST.net/Transformer.cs @@ -22,7 +22,6 @@ public static object valueof(string jsonPath, string inputJson) return GetValue(selectedToken); } - public static string exists(string jsonPath, string inputJson) { JsonReader reader = new JsonTextReader(new StringReader(inputJson)); @@ -74,6 +73,18 @@ public static string concat(string string1, string string2, string inputJson) return string1 != null ? string1 + string2Result : string.Empty + string2Result; } + /// + /// Compare to values + /// + /// Basic value + /// Value to compare with + /// Json object + /// True if the objects are equal + public static bool equals(string @this, string other, string inputJson) + { + return @this == other; + } + public static string substring(string stringRef, string startIndex, string length, string inputJson) { try From bcead83401f8e447edbe5d913a7d9d3ceff3875a Mon Sep 17 00:00:00 2001 From: beggers Date: Sun, 20 Jan 2019 17:29:08 +0100 Subject: [PATCH 02/43] Format readme --- JUST.NET.Test.sln | 5 + README.md | 392 +++++++++++++++++++++++++++++++--------------- 2 files changed, 272 insertions(+), 125 deletions(-) diff --git a/JUST.NET.Test.sln b/JUST.NET.Test.sln index 21b84ea..9af32c1 100644 --- a/JUST.NET.Test.sln +++ b/JUST.NET.Test.sln @@ -9,6 +9,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JUST.net", "JUST.net\JUST.n EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExternalMethods", "ExternalMethods\ExternalMethods.csproj", "{15F60FAC-38CF-4AA7-B369-E738702AA94E}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ENV", "ENV", "{FF566713-3F06-4A89-9127-1916A9DB3C3E}" + ProjectSection(SolutionItems) = preProject + README.md = README.md + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/README.md b/README.md index 7e759f5..90e7bea 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,8 @@ http://www.newtonsoft.com/json/help/html/QueryJsonSelectTokenJsonPath.htm Consider the input:- -``{ +```json +{ "menu": { "popup": { "menuitem": [ @@ -67,22 +68,27 @@ Consider the input:- ] } } -}`` +} +``` Transformer:- -``{ +```json +{ "result": { "Open": "#valueof($.menu.popup.menuitem[?(@.value=='Open')].onclick)", "Close": "#valueof($.menu.popup.menuitem[?(@.value=='Close')].onclick)" } -}`` +} +``` Output:- -``{ +```json +{ "result":{"Open": "OpenDoc()", "Close": "CloseDoc()"} -}`` +} +``` ## ifcondition @@ -95,26 +101,32 @@ All four of the parameters can be a 'valueof' expressions or constants. Consider the input:- -``{ +```json +{ "menu": { "id" : "github", "repository" : "JUST" } -}`` +} +``` Transformer:- -``{ +```json +{ "ifconditiontesttrue": "#ifcondition(#valueof($.menu.id),github,#valueof($.menu.repository),fail)", "ifconditiontestfalse": "#ifcondition(#valueof($.menu.id),xml,#valueof($.menu.repository),fail)" -}`` +} +``` Output:- -``{ +```json +{ "ifconditiontesttrue":"JUST", "ifconditiontestfalse":"fail" -}`` +} +``` ## string and math functions @@ -131,14 +143,17 @@ At the moment only the basic and often used string and math functions are provid Consider the input:- -``{ +```json +{ "stringref": "thisisandveryunuasualandlongstring", "numbers": [ "1", "2", "3", "4", "5" ] -}`` +} +``` Transformer:- -``{ +```json +{ "stringresult": { "lastindexofand": "#lastindexof(#valueof($.stringref),and)", "firstindexofand": "#firstindexof(#valueof($.stringref),and)", @@ -151,11 +166,13 @@ Transformer:- "multiply": "#multiply(2,#valueof($.numbers[2]))", "divide": "#divide(9,3)" } -}`` +} +``` Output:- -``{"stringresult": +```json +{"stringresult": { "lastindexofand":"21", "firstindexofand":"6", @@ -169,7 +186,8 @@ Output:- "multiply":"6", "divide":"3" } -}`` +} +``` ## Opearators @@ -185,14 +203,17 @@ The following operators have been added to compare strings and numbers :- Consider the input:- -``{ +```json +{ "d": [ "one", "two", "three" ], "numbers": [ "1", "2", "3", "4", "5" ] -}`` +} +``` Transformer:- -``{ +```json +{ "mathresult": { "third_element_equals_3": "#ifcondition(#mathequals(#valueof($.numbers[2]),3),true,yes,no)", "third_element_greaterthan_2": "#ifcondition(#mathgreaterthan(#valueof($.numbers[2]),2),true,yes,no)", @@ -202,11 +223,24 @@ Transformer:- "one_stringequals": "#ifcondition(#stringequals(#valueof($.d[0]),one),true,yes,no)", "one_stringcontains": "#ifcondition(#stringcontains(#valueof($.d[0]),n),true,yes,no)" } -}`` +} +``` Output:- -``{"mathresult": {"third_element_equals_3":"yes","third_element_greaterthan_2":"yes","third_element_lessthan_4":"yes","third_element_greaterthanorequals_4":"no","third_element_lessthanoreuals_2":"no","one_stringequals":"yes","one_stringcontains":"yes"}} +```json +{ + "mathresult":{ + "third_element_equals_3":"yes", + "third_element_greaterthan_2":"yes", + "third_element_lessthan_4":"yes", + "third_element_greaterthanorequals_4":"no", + "third_element_lessthanoreuals_2":"no", + "one_stringequals":"yes", + "one_stringcontains":"yes" + } +} +``` ## Aggregate functions @@ -220,30 +254,36 @@ The following aggregate functions are provided for single dimensional arrays:- Consider the input:- -``{ +```json +{ "d": [ "one", "two", "three" ], "numbers": [ "1", "2", "3", "4", "5" ] -}`` +} +``` Transformer:- -``{ +```json +{ "conacted": "#concatall(#valueof($.d))", "sum": "#sum(#valueof($.numbers))", "avg": "#average(#valueof($.numbers))", "min": "#min(#valueof($.numbers))", "max": "#max(#valueof($.numbers))" -}`` +} +``` Output:- -``{ +```json +{ "conacted":"onetwothree", "sum":"15", "avg":"3", "min":"1", "max":"5" -}`` +} +``` ## Aggregate functions for multidimensional arrays:- @@ -256,7 +296,8 @@ These functions are essentially the same as the above ones, the only difference Consider the input:- -``{ +```json +{ "x": [ { "v": { @@ -280,27 +321,32 @@ Consider the input:- } } ] -}`` +} +``` Transformer:- -``{ +```json +{ "arrayconacted": "#concatallatpath(#valueof($.x),$.v.a)", "arraysum": "#sumatpath(#valueof($.x),$.v.c)", "arrayavg": "#averageatpath(#valueof($.x),$.v.c)", "arraymin": "#minatpath(#valueof($.x),$.v.b)", "arraymax": "#maxatpath(#valueof($.x),$.v.b)" -}`` +} +``` Output:- -``{ +```json +{ "arrayconacted":"a1,a2,a3b1,b2c1,c2,c3", "arraysum":"60", "arrayavg":"20", "arraymin":"1", "arraymax":"3" -}`` +} +``` ## Bulk functions @@ -317,7 +363,8 @@ These are the bulk functions provided as of now:- Cosider the input:- -``{ +```json +{ "tree": { "branch": { "leaf": "green", @@ -327,18 +374,22 @@ Cosider the input:- }, "ladder": {"wood": "treehouse" } } -}`` +} +``` Transformer:- -``{ +```json +{ "#": [ "#copy($)", "#delete($.tree.branch.bird)", "#replace($.tree.branch.extra,#valueof($.tree.ladder))" ], "othervalue" : "othervalue" -}`` +} +``` Output:- -``{ +```json +{ "othervalue":"othervalue", "tree":{ "branch":{ @@ -352,7 +403,8 @@ Output:- "wood":"treehouse" } } -}`` +} +``` ## Array looping @@ -371,7 +423,8 @@ These are the functions provided for this pupose:- Cosider the input:- -``{ +```json +{ "tree": { "branch": { "leaf": "green", @@ -396,11 +449,13 @@ Cosider the input:- "language": "swedish" } }] -}`` +} +``` Transformer:- -``{ +```json +{ "iteration": { "#loop($.numbers)": { "CurrentValue": "#currentvalue()", @@ -418,11 +473,13 @@ Transformer:- } }, "othervalue": "othervalue" -}`` +} +``` Output:- -``{"iteration":[ +```json +{"iteration":[ {"CurrentValue":"1","CurrentIndex":"0","IsLast":"no","LastValue":"4"}, {"CurrentValue":"2","CurrentIndex":"1","IsLast":"no","LastValue":"4"}, {"CurrentValue":"3","CurrentIndex":"2","IsLast":"no","LastValue":"4"}, @@ -433,12 +490,15 @@ Output:- {"CurrentValue":"UK","CurrentIndex":"1","IsLast":"no","LastValue":"swedish"}, {"CurrentValue":"Sweden","CurrentIndex":"2","IsLast":"yes","LastValue":"swedish"} ], -"othervalue":"othervalue"}`` +"othervalue":"othervalue"} +``` ## Nested array looping (looping within context) A new function `loopwithincontext` has been introduced to be able to loop withing the context of an outer loop. Cosider the input:- -``{ + +```json +{ "NestedLoop": { "Organization": { "Employee": [ @@ -467,10 +527,13 @@ Cosider the input:- ] } } -}`` +} +``` + Transformer:- -``{ +```json +{ "hello": { "#loop($.NestedLoop.Organization.Employee)": { "CurrentName": "#currentvalueatpath($.Name)", @@ -481,17 +544,20 @@ Transformer:- } } } -}`` +} +``` Output:- -``{ +```json +{ "hello": [ {"CurrentName":"E2","Details":[{"CurrentCountry":"Iceland"}]}, {"CurrentName":"E1","Details":[{"CurrentCountry":"Denmark"}]} ] -}`` +} +``` ## Array grouping @@ -501,7 +567,8 @@ grouparrayby(path,groupingElementName,groupedElementName) Input:- -``{ +```json +{ "Forest": [ { "type": "Mammal", @@ -534,17 +601,21 @@ Input:- "name": "Dog" } ] -}`` +} +``` Transformer:- -``{ +```json +{ "Result": "#grouparrayby($.Forest,type,all)" -}`` +} +``` Output:- -``{ +```json +{ "Result":[ { "type":"Mammal", @@ -586,13 +657,15 @@ Output:- ] } ] -}`` +} +``` You can group using multiple "grouping elements". They should be seperated by a semicolon (:) Input:- -``{ +```json +{ "Vehicle": [ { "type": "air", @@ -625,17 +698,21 @@ Input:- "name": "truck" } ] -}`` +} +``` Transformer:- -``{ +```json +{ "Result": "#grouparrayby($.Vehicle,type:company,all)" -}`` +} +``` Output:- -``{ +```json +{ "Result":[ { "type":"air", @@ -680,7 +757,8 @@ Output:- ] } ] -}`` +} +``` ## Calling Custom functions @@ -694,7 +772,8 @@ A custom function is called using the following syntax:- Consider the following input:- -``{ +```json +{ "tree": { "branch": { "leaf": "green", @@ -702,13 +781,16 @@ Consider the following input:- "bird": "crow" } } -}`` +} +``` Transformer:- -``{ +```json +{ "Season": "#customfunction(JUST.NET.Test,JUST.NET.Test.Season.findseason,#valueof($.tree.branch.leaf),#valueof($.tree.branch.flower))" -}`` +} +``` Custom function:- @@ -721,7 +803,9 @@ Custom function:- }` Output:- -``{"Season":"summer"}`` +```json +{"Season":"summer"} +``` ## Calling User Defined methods by name @@ -735,7 +819,8 @@ Here's the syntax:- Consider the following input:- -``{ +```json +{ "season": { "characteristics": { "hot": true, @@ -743,16 +828,21 @@ Consider the following input:- "randomDay": "2018-08-01T00:00:00.000Z" } } -}`` +} +``` Transformer:- -``{ +```json +{ "summer": "#ExternalMethods::SeasonsHelper.Season::IsSummer(#valueof($.season.characteristics.hot),#valueof($.season.characteristics.averageDaysOfRain),#valueof($.season.characteristics.randomDay))" -}`` +} +``` Output:- -``{"summer": true}`` +```json +{"summer": true} +``` ## Complex nested functions @@ -760,17 +850,20 @@ You can easily nest functions to do complex transformations. An example of such Consider the following input:- -``{ +```json +{ "Name": "Kari", "Surname": "Nordmann", "MiddleName": "Inger", "ContactInformation": "Karl johans gate:Oslo:88880000" , "PersonalInformation": "45:Married:Norwegian" -}`` +} +``` Transformer:- -``{ +```json +{ "FullName": "#concat(#concat(#concat(#valueof($.Name), ),#concat(#valueof($.MiddleName), )),#valueof($.Surname))", "Contact Information": { "Street Name": "#substring(#valueof($.ContactInformation),0,#firstindexof(#valueof($.ContactInformation),:))", @@ -780,12 +873,14 @@ Transformer:- "Personal Information": { "Age": "#substring(#valueof($.PersonalInformation),0,#firstindexof(#valueof($.PersonalInformation),:))", "Civil Status": "#substring(#valueof($.PersonalInformation),#add(#firstindexof(#valueof($.PersonalInformation),:),1),#subtract(#subtract(#lastindexof(#valueof($.PersonalInformation),:),#firstindexof(#valueof($.PersonalInformation),:)),1))", -"Ethnicity": "#substring(#valueof($.PersonalInformation),#add(#lastindexof(#valueof($.PersonalInformation),:),1),#subtract(#lastindexof(#valueof($.PersonalInformation),),#lastindexof(#valueof($.PersonalInformation),:)))" - }`` + "Ethnicity": "#substring(#valueof($.PersonalInformation),#add(#lastindexof(#valueof($.PersonalInformation),:),1),#subtract(#lastindexof(#valueof($.PersonalInformation),),#lastindexof(#valueof($.PersonalInformation),:)))" +} +``` Output:- -``{ +```json +{ "FullName":"Kari Inger Nordmann", "Contact Information":{ "Street Name":"Karl johans gate", @@ -797,7 +892,8 @@ Output:- "Civil Status":"Married", "Ethnicity":"Norwegian" } -}`` +} +``` ## Multiple argument & constant functions @@ -812,24 +908,30 @@ Hence, the following 3 functions have been introduced:- Consider the following input:- -``{ +```json +{ "Name": "Kari", "Surname": "Nordmann", "MiddleName": "Inger", "ContactInformation": "Karl johans gate:Oslo:88880000" , "PersonalInformation": "45:Married:Norwegian" -}`` +} +``` Transformer:- -``{ +```json +{ "FullName": "#xconcat(#valueof($.Name),#constant_comma(),#valueof($.MiddleName),#constant_comma(),#valueof($.Surname))", "AgeOfParents": "#xadd(#valueof($.AgeOfMother),#valueof($.AgeOfFather))" -}`` +} +``` Output:- -``{"FullName":"Kari,Inger,Nordmann","AgeOfParents":"67"}`` +```json +{"FullName":"Kari,Inger,Nordmann","AgeOfParents":"67"} +``` ## Check for existance @@ -840,30 +942,36 @@ The following two functions have been added to check for existance:- Consider the following input:- -``{ +```json +{ "BuyDate": "2017-04-10T11:36:39+03:00", "ExpireDate": "" -}`` +} +``` Transformer:- -``{ +```json +{ "BuyDateString": "#ifcondition(#exists($.BuyDate),true,#concat(Buy Date : ,#valueof($.BuyDate)),NotExists)", "BuyDateString2": "#ifcondition(#existsandnotempty($.BuyDate),true,#concat(Buy Date : ,#valueof($.BuyDate)),EmptyOrNotExists)", "ExpireDateString": "#ifcondition(#exists($.ExpireDate),true,#concat(Expire Date : ,#valueof($.ExpireDate)),NotExists)", "ExpireDateString2": "#ifcondition(#existsandnotempty($.ExpireDate),true,#concat(Expire Date : ,#valueof($.ExpireDate)),EmptyOrNotExists)", "SellDateString": "#ifcondition(#exists($.SellDate),true,#concat(Sell Date : ,#valueof($.SellDate)),NotExists)", "SellDateString2": "#ifcondition(#existsandnotempty($.SellDate),true,#concat(Sell Date : ,#valueof($.SellDate)),EmptyOrNotExists)" -}`` +} +``` Output:- -``{"BuyDateString":"Buy Date : 2017-04-10T11:36:39+03:00", +```json +{"BuyDateString":"Buy Date : 2017-04-10T11:36:39+03:00", "BuyDateString2":"Buy Date : 2017-04-10T11:36:39+03:00", "ExpireDateString":"Expire Date : ", "ExpireDateString2":"EmptyOrNotExists", "SellDateString":"NotExists", "SellDateString2":"EmptyOrNotExists" -}`` +} +``` ## Conditional transformation @@ -873,16 +981,19 @@ The function takes an expression as argument which should evaluate to a boolean Consider the following input:- -``{ +```json +{ "Tree": { "Branch": "leaf", "Flower": "Rose" } -}`` +} +``` Transformer:- -``{ +```json +{ "Result": { "Header": "JsonTransform", "#ifgroup(#exists($.Tree.Branch))": { @@ -892,10 +1003,12 @@ Transformer:- } } } -}`` +} +``` Output:- -``{ +```json +{ "Result":{ "Header":"JsonTransform", "State":{ @@ -903,13 +1016,15 @@ Output:- "Value2":"Rose" } } -}`` +} +``` Now, for the same input if we use the following transformer, we get a diferent output. Transformer:- -``{ +```json +{ "Result": { "Header": "JsonTransform", "#ifgroup(#exists($.Tree.Root))": { @@ -919,14 +1034,17 @@ Transformer:- } } } -}`` +} +``` Output:- -``{ +```json +{ "Result":{ "Header":"JsonTransform" } -}`` +} +``` ## Dynamic Properties @@ -935,27 +1053,33 @@ We can now create dynamic properties using the *eval* function. The function tak Consider the following input:- -``{ +```json +{ "Tree": { "Branch": "leaf", "Flower": "Rose" } -}`` +} +``` Transformer:- -``{ +```json +{ "Result": { "#eval(#valueof($.Tree.Flower))": "x" } -}`` +} +``` Output:- -``{ +```json +{ "Result":{ "Rose":"x" } -}`` +} +``` @@ -983,15 +1107,18 @@ In the above case if the validation is un-successful an exception will be thrown Consider the validation input:- -``{ +```json +{ "x.tree": { "x.branch": { "x.leaf": "1" } }, "x.child": 1, "y.animal": 1 -}`` +} +``` Schema X JSON:- -``{ +```json +{ "properties": { "tree": { "type": "object", @@ -1007,16 +1134,18 @@ Schema X JSON:- }, "child": { "type": "string" } } -}`` +} +``` Schema Y JSON:- -``{ +```json +{ "properties": { "animal": { "type": "string" } } } -`` +``` The exception message thrown in the above case would be:- @@ -1033,7 +1162,9 @@ Two new functions have been added for this purpose:- `public static IEnumerable SplitJson(JObject input, string arrayPath)` Consider the input:- -``{ + +```json +{ "cars": { "Ford": [ { @@ -1056,7 +1187,8 @@ Consider the input:- "firstName": "John", "lastName": "Smith", } -}`` +} +``` Below is a sample code which splits the above input:- @@ -1093,7 +1225,9 @@ Sample code to transform from JSON to XML:- ``string transformedString = DataTransformer.Transform(transformer, input);`` Input.json:- -``{ + +```json +{ "menu": { "id": { "file": "csv" @@ -1163,11 +1297,13 @@ Input.json:- "BuyDate": "2017-04-10T11:36:39+03:00", "ExpireDate": "", "LogId": 5000510625 -}`` +} +``` DataTransformer.xml:- -`` +```xml + #ifcondition(#valueof($.menu.id.file),csv,#valueof($.menu.value.Window),fail) @@ -1218,10 +1354,12 @@ DataTransformer.xml:- #valueof($.LogId) } -`` + +``` Output:- -`` +```xml + popup @@ -1299,7 +1437,8 @@ Output:- 5000510625 -`` + +``` ### Example for JSON to CSV @@ -1314,8 +1453,11 @@ DataTransformer.csv:- ``"#loop($.numbers)": {#currentvalue(),#currentindex(),#ifcondition(#currentindex(),#lastindex(),yes,no),#lastvalue(),#valueof($.LogId)}`` Output:- -``1,0,no,5,5000510625 + +```csv +1,0,no,5,5000510625 2,1,no,5,5000510625 3,2,no,5,5000510625 4,3,no,5,5000510625 -5,4,yes,5,5000510625`` +5,4,yes,5,5000510625 +``` From 974918e015c14bda9deffaf2b310923cc7ce00e6 Mon Sep 17 00:00:00 2001 From: beggers Date: Sun, 20 Jan 2019 21:52:27 +0100 Subject: [PATCH 03/43] Add array tests --- Examples/DataTransformer.xml | 15 ++++++++++++++- Examples/Transformer.json | 15 ++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/Examples/DataTransformer.xml b/Examples/DataTransformer.xml index fefa1a7..6327db9 100644 --- a/Examples/DataTransformer.xml +++ b/Examples/DataTransformer.xml @@ -49,5 +49,18 @@ #valueof($.LogId) } - + + + 1 + #valueof($.menu.id.file) + + + 2 + #valueof($.menu.id.file) + + + 3 + #valueof($.menu.id.file) + + \ No newline at end of file diff --git a/Examples/Transformer.json b/Examples/Transformer.json index 9c81647..b1985ee 100644 --- a/Examples/Transformer.json +++ b/Examples/Transformer.json @@ -64,5 +64,18 @@ "Ethnicity": "#substring(#valueof($.PersonalInformation),#add(#lastindexof(#valueof($.PersonalInformation),:),1),#subtract(#lastindexof(#valueof($.PersonalInformation),),#lastindexof(#valueof($.PersonalInformation),:)))", "LogId": "#valueof($.LogId)" }, - + "newArray": [ + { + "nr": "1", + "value": "#valueof($.menu.id.file)" + }, + { + "nr": "2", + "value": "#valueof($.menu.id.file)" + }, + { + "nr": "3", + "value": "#valueof($.menu.id.file)" + } + ] } \ No newline at end of file From 07216ac0068cda985f4abbaf7b1d883317807ecb Mon Sep 17 00:00:00 2001 From: beggers Date: Mon, 21 Jan 2019 09:14:03 +0100 Subject: [PATCH 04/43] Add: getroot Add: getparent Fix: Bracket count Add: Samples --- Examples/Array/base.xml | 38 ++++++++++++++++++++ Examples/Array/input_array.json | 38 ++++++++++++++++++++ Examples/Array/transform_array.json | 15 ++++++++ JUST.NET.Test.csproj | 10 ++++++ JUST.net/JsonTransformer.cs | 55 ++++++++++++++++++----------- JUST.net/Transformer.cs | 21 +++++++++-- Program.cs | 8 +++++ 7 files changed, 162 insertions(+), 23 deletions(-) create mode 100644 Examples/Array/base.xml create mode 100644 Examples/Array/input_array.json create mode 100644 Examples/Array/transform_array.json diff --git a/Examples/Array/base.xml b/Examples/Array/base.xml new file mode 100644 index 0000000..b6bcd53 --- /dev/null +++ b/Examples/Array/base.xml @@ -0,0 +1,38 @@ + + +
+ 1024 + Sample street + 1 +
+
+ 3303 + L-Street + 23 +
+ + 1024 + Max + Sample + + 25 + + + + 1024 + Mina + Sample + + 26 + + + + 3303 + Laura + Rickfield + + 54 + + +
+
\ No newline at end of file diff --git a/Examples/Array/input_array.json b/Examples/Array/input_array.json new file mode 100644 index 0000000..385bae9 --- /dev/null +++ b/Examples/Array/input_array.json @@ -0,0 +1,38 @@ +{ + "root": { + "items": { + "address": [ + { + "id": "001024", + "street": "Sample street", + "houseNr": "1" + }, + { + "id": "003303", + "street": "L-Street", + "houseNr": "23" + } + ], + "inhabitant": [ + { + "addressId": "001024", + "firstName": "Max", + "lastName": "Sample", + "data": { "age": "25" } + }, + { + "addressId": "001024", + "firstName": "Mina", + "lastName": "Sample", + "data": { "age": "26" } + }, + { + "addressId": "003303", + "firstName": "Laura", + "lastName": "Rickfield", + "data": { "age": "54" } + } + ] + } + } +} \ No newline at end of file diff --git a/Examples/Array/transform_array.json b/Examples/Array/transform_array.json new file mode 100644 index 0000000..f18cdce --- /dev/null +++ b/Examples/Array/transform_array.json @@ -0,0 +1,15 @@ +{ + "addresses": { + "#loop($.root.items.address)": { + "id": "#currentvalueatpath($.id)", + "maxAge": "#maxatpath(#getarray(#getroot(), #xconcat($.root.items.inhabitant[?(@.addressId==',#currentvalueatpath($.id),')])), $.data.age)", + "inhabitants": { + "#loop($.root.items.inhabitant[?(@.addressId=='#currentvalueatpath($.id)')])": { + "firstName": "#currentvalueatpath($.firstName)", + "lastName": "#currentvalueatpath($.lastName)", + "parentId": "#valueof(#xconcat($.root.items.address[?(@.id==',#currentvalueatpath($.addressId),')].id))" + } + } + } + } +} \ No newline at end of file diff --git a/JUST.NET.Test.csproj b/JUST.NET.Test.csproj index 5712e2c..e81aac8 100644 --- a/JUST.NET.Test.csproj +++ b/JUST.NET.Test.csproj @@ -63,6 +63,12 @@ Designer + + Always + + + Always + Always @@ -170,6 +176,10 @@ + + Always + Designer + Always diff --git a/JUST.net/JsonTransformer.cs b/JUST.net/JsonTransformer.cs index 1639d42..9633a2e 100644 --- a/JUST.net/JsonTransformer.cs +++ b/JUST.net/JsonTransformer.cs @@ -80,9 +80,6 @@ private static void RecursiveEvaluate(JToken parentToken, string inputJson, JArr foreach (JToken childToken in tokens) { - - - if (childToken.Type == JTokenType.Array && (parentToken as JProperty).Name.Trim() != "#") { JArray arrayToken = childToken as JArray; @@ -159,7 +156,7 @@ private static void RecursiveEvaluate(JToken parentToken, string inputJson, JArr } if (property.Name != null && property.Value.ToString().Trim().StartsWith("#") - && !property.Name.Contains("#eval") && !property.Name.Contains("#ifgroup") + && !property.Name.Contains("#eval") && !property.Name.Contains("#ifgroup") && !property.Name.Contains("#loop")) { object newValue = ParseFunction(property.Value.ToString(), inputJson, parentArray, currentArrayToken); @@ -242,7 +239,7 @@ private static void RecursiveEvaluate(JToken parentToken, string inputJson, JArr if (tokenToForm == null) { - tokenToForm = new List(); + tokenToForm = new List(); } foreach (JToken grandChildToken in childToken.Children()) @@ -308,8 +305,6 @@ private static void RecursiveEvaluate(JToken parentToken, string inputJson, JArr var multipleTokens = token.SelectTokens(strArrayToken); arrayToken = new JArray(multipleTokens); - - } if (arrayToken == null) @@ -351,7 +346,7 @@ private static void RecursiveEvaluate(JToken parentToken, string inputJson, JArr /*End looping */ } - if (childToken.Type == JTokenType.String && childToken.Value().Trim().StartsWith("#") + if (childToken.Type == JTokenType.String && childToken.Value().Trim().StartsWith("#") && parentArray != null && currentArrayToken != null) { @@ -367,7 +362,7 @@ private static void RecursiveEvaluate(JToken parentToken, string inputJson, JArr } catch { - + } } else @@ -581,6 +576,7 @@ private static object ParseFunction(string functionString, string inputJson, JAr { string trimmedArgument = argument; + // Missing contains here! if (argument.Contains("#")) trimmedArgument = argument.Trim(); @@ -597,20 +593,30 @@ private static object ParseFunction(string functionString, string inputJson, JAr parameters[i] = inputJson; - if (functionName == "currentvalue" || functionName == "currentindex" || functionName == "lastindex" + if (functionName == "getroot") + output = inputJson; + else if (functionName == "getparent") + { + if (currentArrayElement == null) + throw new Exception("getparent is only allowed inside loop."); + + output = currentArrayElement.Parent.ToString(); + } + else if (functionName == "currentvalue" || functionName == "currentindex" || functionName == "lastindex" || functionName == "lastvalue") output = ReflectionHelper.caller(null, "JUST.Transformer", functionName, new object[] { array, currentArrayElement }); else if (functionName == "currentvalueatpath" || functionName == "lastvalueatpath") output = ReflectionHelper.caller(null, "JUST.Transformer", functionName, new object[] { array, currentArrayElement, arguments[0] }); else if (functionName == "customfunction") output = CallCustomFunction(parameters); - else if (Regex.IsMatch(functionName, ReflectionHelper.EXTERNAL_ASSEMBLY_REGEX)){ + else if (Regex.IsMatch(functionName, ReflectionHelper.EXTERNAL_ASSEMBLY_REGEX)) + { output = ReflectionHelper.CallExternalAssembly(functionName, parameters); } else if (functionName == "xconcat" || functionName == "xadd" - || functionName == "mathequals" || functionName == "mathgreaterthan" || functionName == "mathlessthan" + || functionName == "mathequals" || functionName == "mathgreaterthan" || functionName == "mathlessthan" || functionName == "mathgreaterthanorequalto" - || functionName == "mathlessthanorequalto" || functionName == "stringcontains" || + || functionName == "mathlessthanorequalto" || functionName == "stringcontains" || functionName == "stringequals") { object[] oParams = new object[1]; @@ -675,16 +681,25 @@ private static string[] GetArguments(string functionString) int openBrackettCount = 0; int closebrackettCount = 0; + var currentArgument = ""; for (int i = 0; i < functionString.Length; i++) { + if (index != 0) + currentArgument = functionString.Substring(index + 1, i - index - 1); + else + currentArgument = functionString.Substring(index, i); + char currentChar = functionString[i]; - if (currentChar == '(') - openBrackettCount++; + if (currentArgument.Trim().StartsWith("#")) + { + if (currentChar == '(') + openBrackettCount++; - if (currentChar == ')') - closebrackettCount++; + if (currentChar == ')') + closebrackettCount++; + } if (openBrackettCount == closebrackettCount) brackettOpen = false; @@ -696,10 +711,8 @@ private static string[] GetArguments(string functionString) if (arguments == null) arguments = new List(); - if (index != 0) - arguments.Add(functionString.Substring(index + 1, i - index - 1)); - else - arguments.Add(functionString.Substring(index, i)); + arguments.Add(currentArgument); + index = i; } diff --git a/JUST.net/Transformer.cs b/JUST.net/Transformer.cs index 69dcffa..512278a 100644 --- a/JUST.net/Transformer.cs +++ b/JUST.net/Transformer.cs @@ -16,12 +16,26 @@ public static object valueof(string jsonPath, string inputJson) JsonReader reader = new JsonTextReader(new StringReader(inputJson)); reader.DateParseHandling = DateParseHandling.None; JToken token = JObject.Load(reader); - //JToken token = JObject.Parse(inputJson); JToken selectedToken = token.SelectToken(jsonPath); return GetValue(selectedToken); } + public static object getarray(string document, string jsonPath, string inputJson) + { + JsonReader reader = new JsonTextReader(new StringReader(document)); + reader.DateParseHandling = DateParseHandling.None; + JToken token = JObject.Load(reader); + + var jsonArrayToken = token.SelectTokens(jsonPath).ToList(); + var array = new JArray(); + foreach (var arrayToken in jsonArrayToken) + array.Add(arrayToken); + + var arrayAsString = array.ToString(); + + return arrayAsString; + } public static string exists(string jsonPath, string inputJson) { @@ -332,7 +346,10 @@ public static string maxatpath(string array, string jsonPath, string inputJson) return integerresult.ToString(); } - catch { return null; } + catch(Exception ex) + { + return null; + } } diff --git a/Program.cs b/Program.cs index 5539cda..b8fbe18 100644 --- a/Program.cs +++ b/Program.cs @@ -14,6 +14,14 @@ class Program { public static void Main(string[] args) { + string inputArrayJson = File.ReadAllText("Examples/Array/input_array.json"); + + string transformerArrayJson = File.ReadAllText("Examples/Array/transform_array.json"); + string transformedArrayJson = JsonTransformer.Transform(transformerArrayJson, inputArrayJson); + Console.WriteLine("################################################################################################"); + Console.WriteLine(transformedArrayJson); + File.WriteAllText("Examples/Array/output_array.json", transformedArrayJson); + string input = File.ReadAllText("Examples/Input.json"); string transformer = File.ReadAllText("Examples/Transformer_valueof.json"); From 96d07b82b5ae9b41bbad35128e75e6cf77f7ab83 Mon Sep 17 00:00:00 2001 From: beggers Date: Mon, 21 Jan 2019 12:59:18 +0100 Subject: [PATCH 05/43] Add first version of createarray --- Examples/Array/transform_array.json | 9 ++- JUST.net/JsonTransformer.cs | 88 ++++++++++++++++++++++------- JUST.net/Transformer.cs | 14 ++++- Program.cs | 2 +- README.md | 22 ++++++++ 5 files changed, 111 insertions(+), 24 deletions(-) diff --git a/Examples/Array/transform_array.json b/Examples/Array/transform_array.json index f18cdce..91bd449 100644 --- a/Examples/Array/transform_array.json +++ b/Examples/Array/transform_array.json @@ -3,11 +3,18 @@ "#loop($.root.items.address)": { "id": "#currentvalueatpath($.id)", "maxAge": "#maxatpath(#getarray(#getroot(), #xconcat($.root.items.inhabitant[?(@.addressId==',#currentvalueatpath($.id),')])), $.data.age)", + "ageSum": "#sumatpath(#getarray(#getroot(), #xconcat($.root.items.inhabitant[?(@.addressId==',#currentvalueatpath($.id),')])), $.data.age)", "inhabitants": { "#loop($.root.items.inhabitant[?(@.addressId=='#currentvalueatpath($.id)')])": { "firstName": "#currentvalueatpath($.firstName)", "lastName": "#currentvalueatpath($.lastName)", - "parentId": "#valueof(#xconcat($.root.items.address[?(@.id==',#currentvalueatpath($.addressId),')].id))" + "parentId": "#valueof(#xconcat($.root.items.address[?(@.id==',#currentvalueatpath($.addressId),')].id))", + "parentStret": "#valueof(#xconcat($.root.items.address[?(@.id==',#currentvalueatpath($.addressId),')].street))" + } + }, + "counter_array": { + "#loop(#createarray(3,count_item,parentId,#currentvalueatpath($.id)))": { + "id": "#currentvalueatpath($.parentId)" } } } diff --git a/JUST.net/JsonTransformer.cs b/JUST.net/JsonTransformer.cs index ff60b0a..ed16134 100644 --- a/JUST.net/JsonTransformer.cs +++ b/JUST.net/JsonTransformer.cs @@ -10,6 +10,8 @@ namespace JUST { public class JsonTransformer { + private const string DefaultTransformerNamespace = "JUST.Transformer"; + public static string Transform(string transformerJson, string inputJson) { JToken result = null; @@ -275,7 +277,8 @@ private static void RecursiveEvaluate(JToken parentToken, string inputJson, JArr reader.DateParseHandling = DateParseHandling.None; JToken token = JObject.Load(reader); JToken arrayToken = null; - if (strArrayToken.Contains("#")) + + if (strArrayToken.Contains("#") && !strArrayToken.Trim().StartsWith("#")) { int sIndex = strArrayToken.IndexOf("#"); string sub1 = strArrayToken.Substring(0, sIndex); @@ -291,20 +294,29 @@ private static void RecursiveEvaluate(JToken parentToken, string inputJson, JArr strArrayToken = sub1 + functionResult + sub2; } } - try + + if (strArrayToken.Trim().StartsWith("#")) { - arrayToken = token.SelectToken(strArrayToken); + arrayToken = ParseFunction(strArrayToken, inputJson, parentArray, currentArrayToken) as JArray; + } - if (arrayToken is JObject) + if (arrayToken == null) + { + try { - arrayToken = new JArray(arrayToken); + arrayToken = token.SelectToken(strArrayToken); + + if (arrayToken is JObject) + { + arrayToken = new JArray(arrayToken); + } } - } - catch - { - var multipleTokens = token.SelectTokens(strArrayToken); + catch + { + var multipleTokens = token.SelectTokens(strArrayToken); - arrayToken = new JArray(multipleTokens); + arrayToken = new JArray(multipleTokens); + } } if (arrayToken == null) @@ -594,7 +606,7 @@ private static object ParseFunction(string functionString, string inputJson, JAr parameters[i] = inputJson; if (functionName == "getroot") - output = inputJson; + output = inputJson; else if (functionName == "getparent") { if (currentArrayElement == null) @@ -602,6 +614,39 @@ private static object ParseFunction(string functionString, string inputJson, JAr output = currentArrayElement.Parent.ToString(); } + else if (functionName == "createarray") + { + var newArray = new JArray(); + + var arrayCount = int.Parse(parameters[0].ToString()); + var arrayItemName = parameters[1].ToString(); + var makeArrayValueParameters = parameters.Skip(2).ToList(); + + for (int elementId = 0; elementId < arrayCount; elementId++) + { + var arrayItem = new JObject(); + + string lastParameterName = null; + for (int parameterId = 0; parameterId < makeArrayValueParameters.Count; parameterId++) + { + if (parameterId % 2 == 0) + lastParameterName = parameters[parameterId].ToString(); + if (parameterId % 2 != 0) + { + arrayItem.Add(new JProperty(lastParameterName, parameters[parameterId])); + + lastParameterName = ""; + } + } + + if (lastParameterName != "") + arrayItem.Add(new JProperty(lastParameterName, null)); + + newArray.Add(arrayItem); + } + + output = newArray; + } else if (functionName == "currentvalue" || functionName == "currentindex" || functionName == "lastindex" || functionName == "lastvalue") output = ReflectionHelper.InvokeFunction(null, "JUST.Transformer", functionName, new object[] { array, currentArrayElement }); @@ -621,7 +666,7 @@ private static object ParseFunction(string functionString, string inputJson, JAr { object[] oParams = new object[1]; oParams[0] = parameters; - output = ReflectionHelper.InvokeFunction(null, "JUST.Transformer", functionName, oParams); + output = ReflectionHelper.InvokeFunction(null, DefaultTransformerNamespace, functionName, oParams); } else { @@ -629,7 +674,7 @@ private static object ParseFunction(string functionString, string inputJson, JAr { parameters[i] = JsonConvert.SerializeObject(currentArrayElement); } - output = ReflectionHelper.InvokeFunction(null, "JUST.Transformer", functionName, parameters); + output = ReflectionHelper.InvokeFunction(null, DefaultTransformerNamespace, functionName, parameters); } return output; @@ -672,8 +717,11 @@ private static object CallCustomFunction(object[] parameters) #endregion #region GetArguments - private static string[] GetArguments(string functionString) + private static string[] GetArguments(string rawArgument) { + if (rawArgument.Trim() == "") + return new string[] { }; + bool brackettOpen = false; List arguments = null; @@ -683,14 +731,14 @@ private static string[] GetArguments(string functionString) int closebrackettCount = 0; var currentArgument = ""; - for (int i = 0; i < functionString.Length; i++) + for (int i = 0; i < rawArgument.Length; i++) { if (index != 0) - currentArgument = functionString.Substring(index + 1, i - index - 1); + currentArgument = rawArgument.Substring(index + 1, i - index - 1); else - currentArgument = functionString.Substring(index, i); + currentArgument = rawArgument.Substring(index, i); - char currentChar = functionString[i]; + char currentChar = rawArgument[i]; if (currentArgument.Trim().StartsWith("#")) { @@ -720,13 +768,13 @@ private static string[] GetArguments(string functionString) if (index > 0) { - arguments.Add(functionString.Substring(index + 1, functionString.Length - index - 1)); + arguments.Add(rawArgument.Substring(index + 1, rawArgument.Length - index - 1)); } else { if (arguments == null) arguments = new List(); - arguments.Add(functionString); + arguments.Add(rawArgument); } return arguments.ToArray(); diff --git a/JUST.net/Transformer.cs b/JUST.net/Transformer.cs index 67068db..2d4b869 100644 --- a/JUST.net/Transformer.cs +++ b/JUST.net/Transformer.cs @@ -21,6 +21,16 @@ public static object valueof(string jsonPath, string inputJson) return GetValue(selectedToken); } + public static string getcurrentscopeasstring(string inputJson) + { + return inputJson; + } + + public static string tostring(object input, string inputJson) + { + return input?.ToString(); + } + public static object getarray(string document, string jsonPath, string inputJson) { JsonReader reader = new JsonTextReader(new StringReader(document)); @@ -490,12 +500,12 @@ public static object lastvalueatpath(JArray array, JToken currentElement, string #region Constants - public static string constant_comma(string none, string inputJson) + public static string constant_comma(string inputJson) { return ","; } - public static string constant_hash(string none, string inputJson) + public static string constant_hash(string inputJson) { return "#"; } diff --git a/Program.cs b/Program.cs index b8fbe18..e828975 100644 --- a/Program.cs +++ b/Program.cs @@ -21,7 +21,7 @@ public static void Main(string[] args) Console.WriteLine("################################################################################################"); Console.WriteLine(transformedArrayJson); File.WriteAllText("Examples/Array/output_array.json", transformedArrayJson); - + return; string input = File.ReadAllText("Examples/Input.json"); string transformer = File.ReadAllText("Examples/Transformer_valueof.json"); diff --git a/README.md b/README.md index 90e7bea..e17ad98 100644 --- a/README.md +++ b/README.md @@ -348,6 +348,28 @@ Output:- } ``` +## Select array using a json path + +`getarray(, )` allows to select an array by using json path. The search is relative to the start object. + +Transformer:- + +```json +{ + "array": #getarray(#getroot(), $.root.items.inhabitant[?(@.firstname=='Max')])) +} +``` + +## Document navigation + +**getroot** + +Returns the root document. + +**getparent** + + + ## Bulk functions All the above functions set property values to predefined properties in the output JSON. However, in some cases we don't know what our output will look like as it depends on the input. From fe04eb4dc6aa8734880252cd36fb2e1885280804 Mon Sep 17 00:00:00 2001 From: beggers Date: Mon, 21 Jan 2019 14:33:06 +0100 Subject: [PATCH 06/43] Fix none --- Examples/Array/transform_array.json | 2 + JUST.net/JsonTransformer.cs | 4 +- JUST.net/Transformer.cs | 69 ++++++++++++++++++++++++++++- 3 files changed, 72 insertions(+), 3 deletions(-) diff --git a/Examples/Array/transform_array.json b/Examples/Array/transform_array.json index 91bd449..509e713 100644 --- a/Examples/Array/transform_array.json +++ b/Examples/Array/transform_array.json @@ -4,6 +4,8 @@ "id": "#currentvalueatpath($.id)", "maxAge": "#maxatpath(#getarray(#getroot(), #xconcat($.root.items.inhabitant[?(@.addressId==',#currentvalueatpath($.id),')])), $.data.age)", "ageSum": "#sumatpath(#getarray(#getroot(), #xconcat($.root.items.inhabitant[?(@.addressId==',#currentvalueatpath($.id),')])), $.data.age)", + "listAtPath": "#listallatpath(#getarray(#getroot(), #xconcat($.root.items.inhabitant[?(@.addressId==',#currentvalueatpath($.id),')])), $.firstName,;)", + "inhabitantsCount": "#count(#getarray(#getroot(), #xconcat($.root.items.inhabitant[?(@.addressId==',#currentvalueatpath($.id),')])))", "inhabitants": { "#loop($.root.items.inhabitant[?(@.addressId=='#currentvalueatpath($.id)')])": { "firstName": "#currentvalueatpath($.firstName)", diff --git a/JUST.net/JsonTransformer.cs b/JUST.net/JsonTransformer.cs index ed16134..c1ebf2f 100644 --- a/JUST.net/JsonTransformer.cs +++ b/JUST.net/JsonTransformer.cs @@ -630,10 +630,10 @@ private static object ParseFunction(string functionString, string inputJson, JAr for (int parameterId = 0; parameterId < makeArrayValueParameters.Count; parameterId++) { if (parameterId % 2 == 0) - lastParameterName = parameters[parameterId].ToString(); + lastParameterName = makeArrayValueParameters[parameterId].ToString(); if (parameterId % 2 != 0) { - arrayItem.Add(new JProperty(lastParameterName, parameters[parameterId])); + arrayItem.Add(new JProperty(lastParameterName, makeArrayValueParameters[parameterId])); lastParameterName = ""; } diff --git a/JUST.net/Transformer.cs b/JUST.net/Transformer.cs index 2d4b869..0b22d4c 100644 --- a/JUST.net/Transformer.cs +++ b/JUST.net/Transformer.cs @@ -151,7 +151,7 @@ public static string concatall(string array, string inputJson) return result; } - public static string concatallatpath(string array, string jsonPath, string inputJson) + public static string listall(string array, string separator, string inputJson) { string result = null; @@ -159,10 +159,38 @@ public static string concatallatpath(string array, string jsonPath, string input if (parsedArray != null) { + var isFirstItem = true; foreach (JToken token in parsedArray.Children()) { + if (result == null) + result = string.Empty; + + if (!isFirstItem && !string.IsNullOrWhiteSpace(result)) + { + result += separator; + } + isFirstItem = false; + + result += token.ToString(); + } + } + + return result; + } + + public static string concatallatpath(string array, string jsonPath, string inputJson) + { + string result = null; + + JArray parsedArray = JArray.Parse(array); + + if (parsedArray != null) + { + + foreach (JToken token in parsedArray.Children()) + { JToken selectedToken = token.SelectToken(jsonPath); if (result == null) @@ -175,6 +203,35 @@ public static string concatallatpath(string array, string jsonPath, string input return result; } + public static string listallatpath(string array, string jsonPath, string separator, string inputJson) + { + string result = null; + + JArray parsedArray = JArray.Parse(array); + + if (parsedArray != null) + { + var isFirstItem = true; + foreach (JToken token in parsedArray.Children()) + { + JToken selectedToken = token.SelectToken(jsonPath); + + if (result == null) + result = string.Empty; + + if (!isFirstItem && !string.IsNullOrWhiteSpace(result)) + { + result += separator; + } + + isFirstItem = false; + + result += selectedToken.ToString(); + } + } + + return result; + } #endregion #region math functions @@ -206,6 +263,16 @@ public static string divide(string num1, string num2, string inputJson) #endregion #region aggregate functions + public static object count(string array, string inputJson) + { + try + { + JArray parsedArray = JArray.Parse(array); + return parsedArray.Count; + } + catch { return null; } + } + public static string sum(string array, string inputJson) { try From 482e725f84ccbc3119109bf0ec0cdce9cc00f798 Mon Sep 17 00:00:00 2001 From: beggers Date: Mon, 21 Jan 2019 17:03:38 +0100 Subject: [PATCH 07/43] Fix empty array bug --- JUST.net/Transformer.cs | 67 ++++++++++++++++++++++++++++++++--------- JUST.net/Utilities.cs | 8 ++++- Program.cs | 4 +-- 3 files changed, 62 insertions(+), 17 deletions(-) diff --git a/JUST.net/Transformer.cs b/JUST.net/Transformer.cs index 0b22d4c..f328cb1 100644 --- a/JUST.net/Transformer.cs +++ b/JUST.net/Transformer.cs @@ -7,6 +7,39 @@ using System.Globalization; using System.IO; +namespace Simplic.Cloud.DataPort.Service.CustomJUST +{ + public class Str2DateTime + { + public static string str2datetime(string str) + { + if (string.IsNullOrEmpty(str)) + return str; + + if (str.Length < 14) + return str; + + try + { + var year = str.Substring(0, 4); + var month = str.Substring(4, 2); + var day = str.Substring(6, 2); + + var hour = str.Substring(8, 2); + var minute = str.Substring(10, 2); + var second = str.Substring(12, 2); + + return $"{year}-{month}-{day} {hour}:{minute}:{second}"; + } + catch (System.Exception ex) + { + return str; + // todo: log the error + } + } + } +} + namespace JUST { internal class Transformer @@ -136,7 +169,7 @@ public static string concatall(string array, string inputJson) { string result = null; - JArray parsedArray = JArray.Parse(array); + JArray parsedArray = Utilities.ParseOrGetEmpty(array); if (parsedArray != null) { @@ -155,7 +188,7 @@ public static string listall(string array, string separator, string inputJson) { string result = null; - JArray parsedArray = JArray.Parse(array); + JArray parsedArray = Utilities.ParseOrGetEmpty(array); if (parsedArray != null) { @@ -184,7 +217,7 @@ public static string concatallatpath(string array, string jsonPath, string input { string result = null; - JArray parsedArray = JArray.Parse(array); + JArray parsedArray = Utilities.ParseOrGetEmpty(array); if (parsedArray != null) { @@ -193,6 +226,9 @@ public static string concatallatpath(string array, string jsonPath, string input { JToken selectedToken = token.SelectToken(jsonPath); + if (selectedToken == null) + continue; + if (result == null) result = string.Empty; @@ -207,7 +243,7 @@ public static string listallatpath(string array, string jsonPath, string separat { string result = null; - JArray parsedArray = JArray.Parse(array); + JArray parsedArray = Utilities.ParseOrGetEmpty(array); if (parsedArray != null) { @@ -216,6 +252,9 @@ public static string listallatpath(string array, string jsonPath, string separat { JToken selectedToken = token.SelectToken(jsonPath); + if (selectedToken == null) + continue; + if (result == null) result = string.Empty; @@ -267,7 +306,7 @@ public static object count(string array, string inputJson) { try { - JArray parsedArray = JArray.Parse(array); + JArray parsedArray = Utilities.ParseOrGetEmpty(array); return parsedArray.Count; } catch { return null; } @@ -277,7 +316,7 @@ public static string sum(string array, string inputJson) { try { - JArray parsedArray = JArray.Parse(array); + JArray parsedArray = Utilities.ParseOrGetEmpty(array); double integerresult = 0; @@ -301,7 +340,7 @@ public static string sumatpath(string array, string jsonPath, string inputJson) { double integerresult = 0; - JArray parsedArray = JArray.Parse(array); + JArray parsedArray = Utilities.ParseOrGetEmpty(array); if (parsedArray != null) { @@ -325,7 +364,7 @@ public static string average(string array, string inputJson) { try { - JArray parsedArray = JArray.Parse(array); + JArray parsedArray = Utilities.ParseOrGetEmpty(array); double integerresult = 0; @@ -349,7 +388,7 @@ public static string averageatpath(string array, string jsonPath, string inputJs { double integerresult = 0; - JArray parsedArray = JArray.Parse(array); + JArray parsedArray = Utilities.ParseOrGetEmpty(array); if (parsedArray != null) { @@ -373,7 +412,7 @@ public static string max(string array, string inputJson) { try { - JArray parsedArray = JArray.Parse(array); + JArray parsedArray = Utilities.ParseOrGetEmpty(array); double integerresult = 0; int i = 0; @@ -408,7 +447,7 @@ public static string maxatpath(string array, string jsonPath, string inputJson) double integerresult = 0; int i = 0; - JArray parsedArray = JArray.Parse(array); + JArray parsedArray = Utilities.ParseOrGetEmpty(array); if (parsedArray != null) { @@ -446,7 +485,7 @@ public static string min(string array, string inputJson) { try { - JArray parsedArray = JArray.Parse(array); + JArray parsedArray = Utilities.ParseOrGetEmpty(array); double integerresult = 0; int i = 0; @@ -481,7 +520,7 @@ public static string minatpath(string array, string jsonPath, string inputJson) double integerresult = 0; int i = 0; - JArray parsedArray = JArray.Parse(array); + JArray parsedArray = Utilities.ParseOrGetEmpty(array); if (parsedArray != null) { @@ -515,7 +554,7 @@ public static string arraylength(string array, string inputJson) { try { - JArray parsedArray = JArray.Parse(array); + JArray parsedArray = Utilities.ParseOrGetEmpty(array); return parsedArray.Count.ToString(); diff --git a/JUST.net/Utilities.cs b/JUST.net/Utilities.cs index 5139007..612f471 100644 --- a/JUST.net/Utilities.cs +++ b/JUST.net/Utilities.cs @@ -19,7 +19,13 @@ public static IDictionary FlattenJson(string inputJson) return result; } - + public static JArray ParseOrGetEmpty(string arrayTokens) + { + if (string.IsNullOrWhiteSpace(arrayTokens)) + arrayTokens = "[]"; + + return JArray.Parse(arrayTokens); + } private static Dictionary PopulateRecursively(JToken parent, Dictionary result) { diff --git a/Program.cs b/Program.cs index e828975..40dd7c0 100644 --- a/Program.cs +++ b/Program.cs @@ -14,9 +14,9 @@ class Program { public static void Main(string[] args) { - string inputArrayJson = File.ReadAllText("Examples/Array/input_array.json"); + string inputArrayJson = File.ReadAllText("Examples/Array/nz_input.json"); - string transformerArrayJson = File.ReadAllText("Examples/Array/transform_array.json"); + string transformerArrayJson = File.ReadAllText("Examples/Array/nz_transformer.json"); string transformedArrayJson = JsonTransformer.Transform(transformerArrayJson, inputArrayJson); Console.WriteLine("################################################################################################"); Console.WriteLine(transformedArrayJson); From 5e554c8f46a95bca63941e9c7a11a9d642bdbfc1 Mon Sep 17 00:00:00 2001 From: beggers Date: Mon, 21 Jan 2019 17:04:43 +0100 Subject: [PATCH 08/43] Remove test code --- JUST.net/Transformer.cs | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/JUST.net/Transformer.cs b/JUST.net/Transformer.cs index f328cb1..2fb9f1e 100644 --- a/JUST.net/Transformer.cs +++ b/JUST.net/Transformer.cs @@ -1,45 +1,9 @@ using System; -using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using System.Globalization; using System.IO; -namespace Simplic.Cloud.DataPort.Service.CustomJUST -{ - public class Str2DateTime - { - public static string str2datetime(string str) - { - if (string.IsNullOrEmpty(str)) - return str; - - if (str.Length < 14) - return str; - - try - { - var year = str.Substring(0, 4); - var month = str.Substring(4, 2); - var day = str.Substring(6, 2); - - var hour = str.Substring(8, 2); - var minute = str.Substring(10, 2); - var second = str.Substring(12, 2); - - return $"{year}-{month}-{day} {hour}:{minute}:{second}"; - } - catch (System.Exception ex) - { - return str; - // todo: log the error - } - } - } -} - namespace JUST { internal class Transformer From 0aae155f2940a776bb3d7d5833b644d5081ab3e0 Mon Sep 17 00:00:00 2001 From: beggers Date: Mon, 21 Jan 2019 17:09:29 +0100 Subject: [PATCH 09/43] Enable all tests --- Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Program.cs b/Program.cs index 40dd7c0..061410f 100644 --- a/Program.cs +++ b/Program.cs @@ -21,7 +21,7 @@ public static void Main(string[] args) Console.WriteLine("################################################################################################"); Console.WriteLine(transformedArrayJson); File.WriteAllText("Examples/Array/output_array.json", transformedArrayJson); - return; + string input = File.ReadAllText("Examples/Input.json"); string transformer = File.ReadAllText("Examples/Transformer_valueof.json"); From 9184537677fca1c105234fee991b93c403fb0d52 Mon Sep 17 00:00:00 2001 From: beggers Date: Mon, 21 Jan 2019 17:10:27 +0100 Subject: [PATCH 10/43] Fix path --- Program.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Program.cs b/Program.cs index 061410f..b8fbe18 100644 --- a/Program.cs +++ b/Program.cs @@ -14,9 +14,9 @@ class Program { public static void Main(string[] args) { - string inputArrayJson = File.ReadAllText("Examples/Array/nz_input.json"); + string inputArrayJson = File.ReadAllText("Examples/Array/input_array.json"); - string transformerArrayJson = File.ReadAllText("Examples/Array/nz_transformer.json"); + string transformerArrayJson = File.ReadAllText("Examples/Array/transform_array.json"); string transformedArrayJson = JsonTransformer.Transform(transformerArrayJson, inputArrayJson); Console.WriteLine("################################################################################################"); Console.WriteLine(transformedArrayJson); From d5e6478a8a02f024488be72bfc64b7d3b8baa1cf Mon Sep 17 00:00:00 2001 From: beggers Date: Mon, 21 Jan 2019 17:43:43 +0100 Subject: [PATCH 11/43] Add: firstatpath --- JUST.net/Transformer.cs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/JUST.net/Transformer.cs b/JUST.net/Transformer.cs index 2fb9f1e..107f545 100644 --- a/JUST.net/Transformer.cs +++ b/JUST.net/Transformer.cs @@ -324,6 +324,30 @@ public static string sumatpath(string array, string jsonPath, string inputJson) catch { return null; } } + public static string firstatpath(string array, string jsonPath, string inputJson) + { + try + { + JArray parsedArray = Utilities.ParseOrGetEmpty(array); + + if (parsedArray != null) + { + + foreach (JToken token in parsedArray.Children()) + { + + JToken selectedToken = token.SelectToken(jsonPath); + + if (selectedToken != null) + return selectedToken?.ToString(); + } + } + + return null; + } + catch { return null; } + } + public static string average(string array, string inputJson) { try From f41040ed0e24ba3ef794f7f6b5a929af5c236d9e Mon Sep 17 00:00:00 2001 From: beggers Date: Tue, 22 Jan 2019 09:33:34 +0100 Subject: [PATCH 12/43] . --- JUST.net/Transformer.cs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/JUST.net/Transformer.cs b/JUST.net/Transformer.cs index 107f545..8ceeb16 100644 --- a/JUST.net/Transformer.cs +++ b/JUST.net/Transformer.cs @@ -119,6 +119,38 @@ public static string substring(string stringRef, string startIndex, string lengt } } + public static string trimstart(string value, string trimChar, string inputJson) + { + if (string.IsNullOrEmpty(trimChar)) + return value; + + return value?.TrimStart(trimChar[0]); + } + + public static string trimend(string value, string trimChar, string inputJson) + { + if (string.IsNullOrEmpty(trimChar)) + return value; + + return value?.TrimEnd(trimChar[0]); + } + + public static string trim(string value, string inputJson) + { + return value?.Trim(); + } + + public static string replacestring(string value, string searchString, string replaceString, string inputJson) + { + if (searchString == null) + return value; + + if (replaceString == null) + return value; + + return value?.Replace(searchString, replaceString); + } + public static string firstindexof(string stringRef, string searchString, string inputJson) { return stringRef.IndexOf(searchString, 0).ToString(); From 6329132e0094c0636c6a5ca37118f39296eadbe2 Mon Sep 17 00:00:00 2001 From: beggers Date: Thu, 24 Jan 2019 14:53:38 +0100 Subject: [PATCH 13/43] . --- .../Properties/PublishProfiles/FolderProfile.pubxml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/JUST.net/Properties/PublishProfiles/FolderProfile.pubxml b/JUST.net/Properties/PublishProfiles/FolderProfile.pubxml index 5672e42..cef52a6 100644 --- a/JUST.net/Properties/PublishProfiles/FolderProfile.pubxml +++ b/JUST.net/Properties/PublishProfiles/FolderProfile.pubxml @@ -1,13 +1,13 @@  FileSystem - Release - netstandard1.6 - bin\Release\PublishOutput + Debug + netstandard2.0 + bin\Debug\PublishOutput + Any CPU \ No newline at end of file From fe49b492a77892c3050664c0ef7ac237961b1dbb Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Tue, 25 Aug 2020 23:19:08 +0200 Subject: [PATCH 14/43] Add azure pipeline --- ExternalMethods/ExternalMethods.csproj | 2 +- JUST.NET.Test.csproj | 4 +- JUST.NET.Test.sln | 5 +- JUST.net/JUST.net.csproj | 4 +- azure-pipelines.yml | 63 ++++++++++++++++++++++++++ packages.config | 4 +- 6 files changed, 73 insertions(+), 9 deletions(-) create mode 100644 azure-pipelines.yml diff --git a/ExternalMethods/ExternalMethods.csproj b/ExternalMethods/ExternalMethods.csproj index 7977d1b..6e86919 100644 --- a/ExternalMethods/ExternalMethods.csproj +++ b/ExternalMethods/ExternalMethods.csproj @@ -5,7 +5,7 @@ - + diff --git a/JUST.NET.Test.csproj b/JUST.NET.Test.csproj index e81aac8..ba1f2f9 100644 --- a/JUST.NET.Test.csproj +++ b/JUST.NET.Test.csproj @@ -38,10 +38,10 @@ - packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll + packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll - packages\Newtonsoft.Json.Schema.3.0.10\lib\net45\Newtonsoft.Json.Schema.dll + packages\Newtonsoft.Json.Schema.3.0.13\lib\net45\Newtonsoft.Json.Schema.dll diff --git a/JUST.NET.Test.sln b/JUST.NET.Test.sln index 9af32c1..6218ee9 100644 --- a/JUST.NET.Test.sln +++ b/JUST.NET.Test.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26730.10 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30413.136 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JUST.NET.Test", "JUST.NET.Test.csproj", "{507F2FFD-22BD-433E-9CEC-0B210DF18ED3}" EndProject @@ -11,6 +11,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExternalMethods", "External EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ENV", "ENV", "{FF566713-3F06-4A89-9127-1916A9DB3C3E}" ProjectSection(SolutionItems) = preProject + azure-pipelines.yml = azure-pipelines.yml README.md = README.md EndProjectSection EndProject diff --git a/JUST.net/JUST.net.csproj b/JUST.net/JUST.net.csproj index dd0f448..a0d95ae 100644 --- a/JUST.net/JUST.net.csproj +++ b/JUST.net/JUST.net.csproj @@ -17,8 +17,8 @@ https://github.com/WorkMaze/JUST.net/issues/25 - - + + diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 0000000..bdcb7e1 --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,63 @@ +trigger: + branches: + include: + - master + - dev + paths: + include: + - src/* + - test/* + - azure-pipelines.yml + +pr: + branches: + include: + - '*' + +pool: + vmImage: 'windows-latest' + +variables: + buildConfiguration: 'Release' + +steps: +- task: NuGetToolInstaller@1 + inputs: + versionSpec: '5.x' + +- task: NuGetCommand@2 + inputs: + command: 'restore' + restoreSolution: 'JUST.NET.Test.sln' + feedsToUse: 'select' + vstsFeed: 'f7087ef5-bf6f-48b2-8b8b-5e513f4a7a9e' + +- task: MSBuild@1 + inputs: + solution: 'JUST.NET.Test.sln' + configuration: '$(buildConfiguration)' + +- task: VSTest@2 + inputs: + testSelector: 'testAssemblies' + testAssemblyVer2: | + **\JUST.NET.Test.dll + !**\*TestAdapter.dll + !**\obj\** + searchFolder: 'src' + +- task: NuGetCommand@2 + inputs: + command: 'pack' + packagesToPack: 'src/**/JUST.net.csproj;!src/JUST.NET.Test/JUST.NET.Test.csproj' + configuration: '$(buildConfiguration)' + versioningScheme: 'off' + +- task: NuGetCommand@2 + condition: eq(variables['Build.SourceBranch'], 'refs/heads/master') + inputs: + command: 'push' + packagesToPush: '$(Build.ArtifactStagingDirectory)/JUST.net.*.nupkg;!$(Build.ArtifactStagingDirectory)/JUST.net.*.symbols.nupkg' + nuGetFeedType: 'internal' + publishVstsFeed: 'f7087ef5-bf6f-48b2-8b8b-5e513f4a7a9e' + allowPackageConflicts: true diff --git a/packages.config b/packages.config index 0033278..c983e22 100644 --- a/packages.config +++ b/packages.config @@ -1,7 +1,7 @@  - - + + From 2d7ab2e931ae9564df1ef22d16d1cefd943c2d72 Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Tue, 25 Aug 2020 23:24:40 +0200 Subject: [PATCH 15/43] Remove tests --- JUST.net/JUST.net.csproj | 8 ++++++++ azure-pipelines.yml | 11 +---------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/JUST.net/JUST.net.csproj b/JUST.net/JUST.net.csproj index a0d95ae..a0204e8 100644 --- a/JUST.net/JUST.net.csproj +++ b/JUST.net/JUST.net.csproj @@ -16,6 +16,14 @@ https://github.com/WorkMaze/JUST.net/issues/26 https://github.com/WorkMaze/JUST.net/issues/25 + + bin\Release + + + + bin\Release + + diff --git a/azure-pipelines.yml b/azure-pipelines.yml index bdcb7e1..84d570e 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -37,19 +37,10 @@ steps: solution: 'JUST.NET.Test.sln' configuration: '$(buildConfiguration)' -- task: VSTest@2 - inputs: - testSelector: 'testAssemblies' - testAssemblyVer2: | - **\JUST.NET.Test.dll - !**\*TestAdapter.dll - !**\obj\** - searchFolder: 'src' - - task: NuGetCommand@2 inputs: command: 'pack' - packagesToPack: 'src/**/JUST.net.csproj;!src/JUST.NET.Test/JUST.NET.Test.csproj' + packagesToPack: 'src/**/JUST.net.csproj;!src/**/JUST.NET.Test.csproj' configuration: '$(buildConfiguration)' versioningScheme: 'off' From ae1c765a58d7793d9a29eb97c455043708d42dfa Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Tue, 25 Aug 2020 23:30:11 +0200 Subject: [PATCH 16/43] Do not create package on build --- JUST.net/JUST.net.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/JUST.net/JUST.net.csproj b/JUST.net/JUST.net.csproj index a0204e8..2dad668 100644 --- a/JUST.net/JUST.net.csproj +++ b/JUST.net/JUST.net.csproj @@ -9,7 +9,7 @@ This will repace the JUST and JUST.NETCore packages. https://github.com/WorkMaze/JUST.net/blob/master/License.md C#;.NET;JSON;XSLT;Transformation;Schema https://github.com/WorkMaze/JUST.net - true + false true Fixed the following issues:- https://github.com/WorkMaze/JUST.net/issues/26 From 72db89aaf0ed2cfaa96fd0538845bff99da7b552 Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Tue, 25 Aug 2020 23:33:17 +0200 Subject: [PATCH 17/43] Fix path --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 84d570e..12206e5 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -40,7 +40,7 @@ steps: - task: NuGetCommand@2 inputs: command: 'pack' - packagesToPack: 'src/**/JUST.net.csproj;!src/**/JUST.NET.Test.csproj' + packagesToPack: '**/JUST.net.csproj;!**/JUST.NET.Test.csproj' configuration: '$(buildConfiguration)' versioningScheme: 'off' From 9ff635a96bde9b3fb7e0213ecfbd7713b844e7a3 Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Tue, 25 Aug 2020 23:39:18 +0200 Subject: [PATCH 18/43] Fix project --- JUST.net/JUST.net.csproj | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/JUST.net/JUST.net.csproj b/JUST.net/JUST.net.csproj index 2dad668..fde7be3 100644 --- a/JUST.net/JUST.net.csproj +++ b/JUST.net/JUST.net.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 @@ -14,6 +14,9 @@ This will repace the JUST and JUST.NETCore packages. Fixed the following issues:- https://github.com/WorkMaze/JUST.net/issues/26 https://github.com/WorkMaze/JUST.net/issues/25 + 5.6.20.825 + 5.6.20.825 + 5.6.20 @@ -21,7 +24,7 @@ https://github.com/WorkMaze/JUST.net/issues/25 - bin\Release + bin\Debug From 2dfcc0a1d0b69101b551a7f2fe619497256448e0 Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Thu, 3 Sep 2020 21:46:46 +0200 Subject: [PATCH 19/43] Cleanup JUST.Net, to pure json transformer --- JUST.NET.Test.csproj | 205 ----------------- JUST.NET.Test.sln => JUST.NET.sln | 2 - JUST.net/DataTransformer.cs | 356 ------------------------------ JUST.net/Parser.cs | 195 ---------------- JUST.net/Utilities.cs | 38 ---- Program.cs | 219 ------------------ azure-pipelines.yml | 6 +- 7 files changed, 3 insertions(+), 1018 deletions(-) delete mode 100644 JUST.NET.Test.csproj rename JUST.NET.Test.sln => JUST.NET.sln (93%) delete mode 100644 JUST.net/DataTransformer.cs delete mode 100644 JUST.net/Parser.cs delete mode 100644 Program.cs diff --git a/JUST.NET.Test.csproj b/JUST.NET.Test.csproj deleted file mode 100644 index ba1f2f9..0000000 --- a/JUST.NET.Test.csproj +++ /dev/null @@ -1,205 +0,0 @@ - - - - - Debug - AnyCPU - {507F2FFD-22BD-433E-9CEC-0B210DF18ED3} - Exe - Properties - JUST.NET.Test - JUST.NET.Test - v4.6.1 - 512 - true - - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll - - - packages\Newtonsoft.Json.Schema.3.0.13\lib\net45\Newtonsoft.Json.Schema.dll - - - - - - - - - - - - - - - - - - - - Designer - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Designer - - - - - Always - Designer - - - Always - - - - - {15f60fac-38cf-4aa7-b369-e738702aa94e} - ExternalMethods - - - {c33053bc-a3f2-4f0a-9b7f-b0af5ad4effb} - JUST.net - - - - - \ No newline at end of file diff --git a/JUST.NET.Test.sln b/JUST.NET.sln similarity index 93% rename from JUST.NET.Test.sln rename to JUST.NET.sln index 6218ee9..22b23f2 100644 --- a/JUST.NET.Test.sln +++ b/JUST.NET.sln @@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.30413.136 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JUST.NET.Test", "JUST.NET.Test.csproj", "{507F2FFD-22BD-433E-9CEC-0B210DF18ED3}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JUST.net", "JUST.net\JUST.net.csproj", "{C33053BC-A3F2-4F0A-9B7F-B0AF5AD4EFFB}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExternalMethods", "ExternalMethods\ExternalMethods.csproj", "{15F60FAC-38CF-4AA7-B369-E738702AA94E}" diff --git a/JUST.net/DataTransformer.cs b/JUST.net/DataTransformer.cs deleted file mode 100644 index 60c2522..0000000 --- a/JUST.net/DataTransformer.cs +++ /dev/null @@ -1,356 +0,0 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; - -namespace JUST -{ - public class DataTransformer - { - private static string Parse(string transformer, string inputJson, JArray array, JToken currentArrayElement) - { - int startIndex = 0, index = 0; - - while ((startIndex < transformer.Length) && (index = transformer.IndexOf('#', startIndex)) != -1) - { - string functionString = GetFunctionString(transformer, index); - - - if (functionString != null) - { - if (functionString.Contains("loop")) - { - string loopArgsInclusive = GetLoopArguments(index, transformer, true); - string loopArgs = GetLoopArguments(index, transformer, false); - - string evaluatedFunction = (string)EvaluateFunction(functionString, inputJson, array, currentArrayElement, loopArgs); - - - StringBuilder builder = new StringBuilder(transformer); - builder.Remove(index-1, loopArgsInclusive.Length+1); - builder.Insert(index-1, evaluatedFunction); - transformer = builder.ToString(); - - startIndex = index + evaluatedFunction.Length; - - } - else - { - - string evaluatedFunction = (string)EvaluateFunction(functionString, inputJson, array, currentArrayElement, null); - - if (!string.IsNullOrEmpty(evaluatedFunction)) - { - - StringBuilder builder = new StringBuilder(transformer); - builder.Remove(index, functionString.Length); - builder.Insert(index, evaluatedFunction); - transformer = builder.ToString(); - - startIndex = index + evaluatedFunction.Length; - } - } - } - else - break; - } - - return transformer; - } - - public static string Transform(string transformer, string inputJson) - { - - return Parse(transformer, inputJson,null,null); - - } - - private static string GetLoopArguments(int startIdex, string input,bool inclusive) - { - string loopArgs = string.Empty; - - - int openBrackettCount = 0; - int closebrackettCount = 0; - - - int bStartIndex = 0; - int bEndIndex = 0; - for (int i = startIdex; i < input.Length; i++) - { - char currentChar = input[i]; - - if (currentChar == '{') - { - if (openBrackettCount == 0) - bStartIndex = i; - - openBrackettCount++; - } - - if (currentChar == '}') - { - bEndIndex = i; - closebrackettCount++; - } - - - - if (openBrackettCount > 0 && openBrackettCount == closebrackettCount) - { - if(!inclusive) - loopArgs = input.Substring(bStartIndex, bEndIndex - bStartIndex + 1); - else - loopArgs = input.Substring(startIdex, bEndIndex - startIdex + 1); - break; - } - - } - - if (inclusive && loopArgs == string.Empty) - return "#loop"; - - return loopArgs; - } - - private static string EvaluateFunction(string functionString, string inputJson, JArray array, JToken currentArrayElement, - string loopArgumentString) - { - string output = null; - - functionString = functionString.Trim().Substring(1); - - int indexOfStart = functionString.IndexOf("("); - - if (indexOfStart != -1) - { - - string functionName = functionString.Substring(0, indexOfStart); - - string argumentString = functionString.Substring(indexOfStart + 1, functionString.Length - indexOfStart - 2); - - string[] arguments = GetArguments(argumentString); - - string[] parameters = new string[arguments.Length + 1]; - - int i = 0; - if (arguments != null && arguments.Length > 0) - { - foreach (string argument in arguments) - { - string trimmedArgument = argument; - - if (argument.Contains("#")) - trimmedArgument = argument.Trim(); - - if (trimmedArgument.StartsWith("#")) - { - parameters[i] = (string)EvaluateFunction(trimmedArgument, inputJson, array, currentArrayElement, loopArgumentString); - } - else - parameters[i] = trimmedArgument; - i++; - } - - } - - parameters[i] = inputJson; - - if (functionName == "loop") - { - output = GetLoopResult(parameters, loopArgumentString); - } - else if (functionName == "currentvalue" || functionName == "currentindex" || functionName == "lastindex" - || functionName == "lastvalue") - output = (string)caller("JUST.Transformer", functionName, new object[] { array, currentArrayElement }); - else if (functionName == "currentvalueatpath" || functionName == "lastvalueatpath") - output = (string)caller("JUST.Transformer", functionName, new object[] { array, currentArrayElement, arguments[0] }); - else if (functionName == "customfunction") - output = (string)CallCustomFunction(parameters); - else if (functionName == "xconcat" || functionName == "xadd" || functionName == "mathequals" || functionName == "mathgreaterthan" || functionName == "mathlessthan" - || functionName == "mathgreaterthanorequalto" - || functionName == "mathlessthanorequalto" || functionName == "stringcontains" || - functionName == "stringequals") - { - object[] oParams = new object[1]; - oParams[0] = parameters; - output = caller("JUST.Transformer", functionName, oParams).ToString(); - } - else - output = caller("JUST.Transformer", functionName, parameters).ToString(); - } - return output; - } - - - private static string GetLoopResult(string[] parameters,string loopArgumentString) - { - string returnString = string.Empty; - - if (parameters.Length < 2) - throw new Exception("Incorrect number of parameters for function #Loop"); - - string input = parameters[1]; - - if (parameters.Length == 3) - input = parameters[2]; - - JsonReader reader = new JsonTextReader(new StringReader(input)); - reader.DateParseHandling = DateParseHandling.None; - JToken token = JObject.Load(reader); - - JToken selectedToken = token.SelectToken(parameters[0]); - - if (selectedToken.Type != JTokenType.Array) - throw new Exception("The JSONPath argument inside a #loop function must be an Array"); - - JArray selectedArr = selectedToken as JArray; - - string seperator = Environment.NewLine; - - if (parameters.Length == 3) - seperator = parameters[1]; - - foreach (JToken arrToken in selectedToken.Children()) - { - string parsedrecord = Parse(loopArgumentString, input, selectedArr, arrToken); - - returnString += parsedrecord.Substring(1, parsedrecord.Length - 2); - returnString += seperator; - } - - return returnString; - } - - private static string GetFunctionString(string input, int startIndex) - { - string functionString = string.Empty; - - int brackettOpenCount = 0; - int brackettClosedCount = 0; - - for(int i = startIndex; i < input.Length; i++) - { - char c = input[i]; - - if (c == '(') - brackettOpenCount++; - if (c == ')') - brackettClosedCount++; - - if( brackettClosedCount > 0 && brackettClosedCount == brackettOpenCount) - { - functionString = input.Substring(startIndex, i - startIndex + 1); - break; - } - } - - return functionString; - } - - private static object CallCustomFunction(object[] parameters) - { - object[] customParameters = new object[parameters.Length - 3]; - string functionString = string.Empty; - string dllName = string.Empty; - int i = 0; - foreach (object parameter in parameters) - { - if (i == 0) - dllName = parameter.ToString(); - else if (i == 1) - functionString = parameter.ToString(); - else - if (i != (parameters.Length - 1)) - customParameters[i - 2] = parameter; - - i++; - } - - int index = functionString.LastIndexOf("."); - - string className = functionString.Substring(0, index); - string functionName = functionString.Substring(index + 1, functionString.Length - index - 1); - - className = className + "," + dllName; - - return caller(className, functionName, customParameters); - - } - - private static object caller(String myclass, String mymethod, object[] parameters) - { - Assembly assembly = Assembly.GetEntryAssembly(); - - Type type = Type.GetType(myclass); - // Create an instance of that type - //Object obj = Activator.CreateInstance(type); - // Retrieve the method you are looking for - MethodInfo methodInfo = type.GetTypeInfo().GetMethod(mymethod); - // Invoke the method on the instance we created above - return methodInfo.Invoke(null, parameters); - } - - - - private static string[] GetArguments(string argumentString) - { - bool brackettOpen = false; - - List arguments = null; - int index = 0; - - int openBrackettCount = 0; - int closebrackettCount = 0; - - for (int i = 0; i < argumentString.Length; i++) - { - char currentChar = argumentString[i]; - - if (currentChar == '(') - openBrackettCount++; - - if (currentChar == ')') - closebrackettCount++; - - if (openBrackettCount == closebrackettCount) - brackettOpen = false; - else - brackettOpen = true; - - if ((currentChar == ',') && (!brackettOpen)) - { - if (arguments == null) - arguments = new List(); - - if (index != 0) - arguments.Add(argumentString.Substring(index + 1, i - index - 1)); - else - arguments.Add(argumentString.Substring(index, i)); - index = i; - } - - } - - if (index > 0) - { - arguments.Add(argumentString.Substring(index + 1, argumentString.Length - index - 1)); - } - else - { - if (arguments == null) - arguments = new List(); - arguments.Add(argumentString); - } - - return arguments.ToArray(); - } - - - } -} diff --git a/JUST.net/Parser.cs b/JUST.net/Parser.cs deleted file mode 100644 index 711c4f5..0000000 --- a/JUST.net/Parser.cs +++ /dev/null @@ -1,195 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace JUST -{ - public class LoopContents - { - public string Evaluated { get; set; } - - public int Start { get; set; } - - public int End { get; set; } - } - - public class Parser - { - - public static string Parse(string input, string loop) - { - int startIndex = 0, index = 0; - - while ((index = input.IndexOf('#', startIndex)) != -1) - { - int endElementIndex = input.IndexOf('"', index); - int startingElementIndex = input.LastIndexOf('"', startIndex); - - - if (endElementIndex > index) - { - startIndex = endElementIndex + 1; - string functionString = input.Substring(index, endElementIndex - index); - - - if (functionString.Trim().Contains("#loop")) - { - LoopContents content = FindLoopContents(input, endElementIndex, functionString); - Console.WriteLine(content.Evaluated); - - StringBuilder builder = new StringBuilder(input); - builder.Remove(content.Start, content.End - content.Start + 1); - builder.Insert(content.Start, content.Evaluated); - input = builder.ToString(); - - startIndex = content.Start + content.Evaluated.Length;// content.End; - -                        //StringBuilder builder = new StringBuilder(input); -                        //builder.Remove(startingElementIndex, content.End - startingElementIndex); -                        //builder.Insert(startingElementIndex, "[" + content.Evaluated + "]"); -                        //input = builder.ToString(); - -                        //startIndex = startingElementIndex + content.Evaluated.Length + 2; -                    } - else - { - StringBuilder builder = new StringBuilder(input); - builder.Remove(index, endElementIndex - index); - string evaluatedFunction = EvaluateFunction(functionString, loop); - builder.Insert(index, evaluatedFunction); - input = builder.ToString(); - - startIndex = index + evaluatedFunction.Length; - } - -                    //Console.WriteLine(functionString); -                } - else - break; - } - - return input; - - - } - - public static string EvaluateFunction(string functionString, string loop) - { - return loop == null ? "SAY_WHAT" : loop + "_YES"; - } - - public static LoopContents FindLoopContents(string input, int startIndex, string loop) - { - - LoopContents contents = new LoopContents(); - - string remainingString = input.Substring(startIndex); - - string result = string.Empty; - - int indexOfColon = remainingString.IndexOf(':'); - - - char searchCharacter = '{'; - bool searchCharaterInitialized = false; - - int opened = 0; - int closed = 0; - - - if (indexOfColon != -1) - { - - remainingString = remainingString.Substring(indexOfColon + 1); - - int startCharIndex = indexOfColon; - - int endCharIndex = indexOfColon; - - int i = 0; - foreach (char c in remainingString) - { - if (c == '"') - { - if (!searchCharaterInitialized) - { - searchCharaterInitialized = true; - searchCharacter = '"'; - startCharIndex = i; - opened++; - } - else - { - if (searchCharaterInitialized && (searchCharacter == '"')) - closed++; - endCharIndex = i; - } - } - if (c == '[') - { - if (!searchCharaterInitialized) - { - searchCharaterInitialized = true; - searchCharacter = '['; - startCharIndex = i; - } - if (searchCharacter == '[') - opened++; - } - if (c == '{') - { - if (!searchCharaterInitialized) - { - searchCharaterInitialized = true; - searchCharacter = '{'; - startCharIndex = i; - } - if (searchCharacter == '{') - opened++; - } - if (c == ']') - { - if (searchCharaterInitialized && (searchCharacter == '[')) - { - closed++; - endCharIndex = i; - } - } - if (c == '}') - { - if (searchCharaterInitialized && (searchCharacter == '{')) - { - closed++; - endCharIndex = i; - } - } - - if (closed > 0 && closed >= opened) - break; - - i++; - } - - result = remainingString.Substring(startCharIndex, endCharIndex - startCharIndex + 1); - - contents.Start = startIndex + startCharIndex + indexOfColon + 1; - contents.End = startIndex + endCharIndex + indexOfColon + 1; - } - - contents.Evaluated = result; - - if (contents.Start == 0) - contents.Start = startIndex + 1; - if (contents.End == 0) - contents.End = startIndex + 1; - - contents.Evaluated = Parse(contents.Evaluated, loop); - - return contents; - } - - - } -} \ No newline at end of file diff --git a/JUST.net/Utilities.cs b/JUST.net/Utilities.cs index 612f471..4c757ef 100644 --- a/JUST.net/Utilities.cs +++ b/JUST.net/Utilities.cs @@ -8,17 +8,6 @@ namespace JUST { public class Utilities { - public static IDictionary FlattenJson(string inputJson) - { - JToken parent = JToken.Parse(inputJson); - - Dictionary result = null; - - result = PopulateRecursively(parent,result); - - return result; - } - public static JArray ParseOrGetEmpty(string arrayTokens) { if (string.IsNullOrWhiteSpace(arrayTokens)) @@ -27,33 +16,6 @@ public static JArray ParseOrGetEmpty(string arrayTokens) return JArray.Parse(arrayTokens); } - private static Dictionary PopulateRecursively(JToken parent, Dictionary result) - { - if (parent.HasValues) - { - foreach (JToken child in parent.Children()) - { - if (child is JProperty) - { - JProperty property = child as JProperty; - - if (result == null) - result = new Dictionary(); - - if(property.Value.HasValues) - { - PopulateRecursively(property.Value, result); - } - else - result.Add(property.Path, property.Value.ToString()); - } - - } - } - - return result; - } - public static JArray GroupArray(JArray array, string groupingPropertyName, string groupedPropertyName) { diff --git a/Program.cs b/Program.cs deleted file mode 100644 index b8fbe18..0000000 --- a/Program.cs +++ /dev/null @@ -1,219 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using JUST; -using System.IO; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - -namespace JUST.NET.Test -{ - class Program - { - public static void Main(string[] args) - { - string inputArrayJson = File.ReadAllText("Examples/Array/input_array.json"); - - string transformerArrayJson = File.ReadAllText("Examples/Array/transform_array.json"); - string transformedArrayJson = JsonTransformer.Transform(transformerArrayJson, inputArrayJson); - Console.WriteLine("################################################################################################"); - Console.WriteLine(transformedArrayJson); - File.WriteAllText("Examples/Array/output_array.json", transformedArrayJson); - - string input = File.ReadAllText("Examples/Input.json"); - - string transformer = File.ReadAllText("Examples/Transformer_valueof.json"); - string transformedString = JsonTransformer.Transform(transformer, input); - Console.WriteLine("################################################################################################"); - Console.WriteLine(transformedString); - - - transformer = File.ReadAllText("Examples/Transformer_valueofarray.json"); - transformedString = JsonTransformer.Transform(transformer, input); - Console.WriteLine("################################################################################################"); - Console.WriteLine(transformedString); - - - transformer = File.ReadAllText("Examples/Transformer_copy.json"); - transformedString = JsonTransformer.Transform(transformer, input); - Console.WriteLine("################################################################################################"); - Console.WriteLine(transformedString); - - transformer = File.ReadAllText("Examples/Transformer_replace.json"); - transformedString = JsonTransformer.Transform(transformer, input); - Console.WriteLine("################################################################################################"); - Console.WriteLine(transformedString); - - transformer = File.ReadAllText("Examples/Transformer_delete.json"); - transformedString = JsonTransformer.Transform(transformer, input); - Console.WriteLine("################################################################################################"); - Console.WriteLine(transformedString); - - - transformer = File.ReadAllText("Examples/Transformer_ifcondition.json"); - transformedString = JsonTransformer.Transform(transformer, input); - Console.WriteLine("################################################################################################"); - Console.WriteLine(transformedString); - - transformer = File.ReadAllText("Examples/Transformer_string.json"); - transformedString = JsonTransformer.Transform(transformer, input); - Console.WriteLine("################################################################################################"); - Console.WriteLine(transformedString); - - transformer = File.ReadAllText("Examples/Transformer_math.json"); - transformedString = JsonTransformer.Transform(transformer, input); - Console.WriteLine("################################################################################################"); - Console.WriteLine(transformedString); - - transformer = File.ReadAllText("Examples/Transformer_aggregate.json"); - transformedString = JsonTransformer.Transform(transformer, input); - Console.WriteLine("################################################################################################"); - Console.WriteLine(transformedString); - - transformer = File.ReadAllText("Examples/Transformer_arrayaggregate.json"); - transformedString = JsonTransformer.Transform(transformer, input); - Console.WriteLine("################################################################################################"); - Console.WriteLine(transformedString); - - transformer = File.ReadAllText("Examples/Transformer_looping.json"); - transformedString = JsonTransformer.Transform(transformer, input); - Console.WriteLine("################################################################################################"); - Console.WriteLine(transformedString); - - transformer = File.ReadAllText("Examples/Transformer_customfunction.json"); - transformedString = JsonTransformer.Transform(transformer, input); - Console.WriteLine("################################################################################################"); - Console.WriteLine(transformedString); - - transformer = File.ReadAllText("Examples/Transformer_nestedfunctions.json"); - transformedString = JsonTransformer.Transform(transformer, input); - Console.WriteLine("################################################################################################"); - Console.WriteLine(transformedString); - - transformer = File.ReadAllText("Examples/Transformer_xfunctions.json"); - transformedString = JsonTransformer.Transform(transformer, input); - Console.WriteLine("################################################################################################"); - Console.WriteLine(transformedString); - - transformer = File.ReadAllText("Examples/Transformer_Existance.json"); - transformedString = JsonTransformer.Transform(transformer, input); - Console.WriteLine("################################################################################################"); - Console.WriteLine(transformedString); - - transformer = File.ReadAllText("Examples/Transformer.json"); - transformedString = JsonTransformer.Transform(transformer, input); - Console.WriteLine("################################################################################################"); - Console.WriteLine(transformedString); - - transformer = File.ReadAllText("Examples/DataTransformer.xml"); - transformedString = DataTransformer.Transform(transformer, input); - Console.WriteLine("################################################################################################"); - Console.WriteLine(transformedString); - - transformer = File.ReadAllText("Examples/DataTransformer.csv"); - transformedString = DataTransformer.Transform(transformer, input); - Console.WriteLine("################################################################################################"); - Console.WriteLine(transformedString); - - transformer = File.ReadAllText("Examples/Transformer.json"); - transformedString = JsonConvert.SerializeObject - (JsonTransformer.Transform(JObject.Parse(transformer), JObject.Parse(input))); - Console.WriteLine(transformedString); - - - - Console.WriteLine("################################################################################################"); - string inputJson = File.ReadAllText("Examples/ValidationInput.json"); - string schemaJsonX = File.ReadAllText("Examples/SchemaX.json"); - string schemaJsonY = File.ReadAllText("Examples/SchemaY.json"); - - string InputToSplit = File.ReadAllText("Examples/InputToSplit.json"); - - List outputs = JsonTransformer.SplitJson(InputToSplit, "$.cars.Ford").ToList(); - - foreach (string output in outputs) - { - Console.WriteLine("-----------------------------------------------------"); - Console.WriteLine(output); - } - - Console.WriteLine("################################################################################################"); - - JsonValidator validator = new JsonValidator(inputJson); - validator.AddSchema("x", schemaJsonX); - validator.AddSchema("y", schemaJsonY); - - validator.Validate(); - - Console.WriteLine("################################################################################################"); - transformer = File.ReadAllText("Examples/Transformer_nestedloop.json"); - transformedString = JsonConvert.SerializeObject - (JsonTransformer.Transform(JObject.Parse(transformer), JObject.Parse(input))); - Console.WriteLine(transformedString); - - Console.WriteLine("################################################################################################"); - transformer = File.ReadAllText("Examples/Transformer_looptests.json"); - transformedString = JsonConvert.SerializeObject - (JsonTransformer.Transform(JObject.Parse(transformer), JObject.Parse(input))); - Console.WriteLine(transformedString); - - Console.WriteLine("################################################################################################"); - - string inputSpecial = File.ReadAllText("Examples/InputSpecial.json"); - transformer = File.ReadAllText("Examples/Transformer_customfunctionspecial.json"); - transformedString = JsonConvert.SerializeObject - (JsonTransformer.Transform(JObject.Parse(transformer), JObject.Parse(inputSpecial))); - Console.WriteLine(transformedString); - - Console.WriteLine("################################################################################################"); - - string inputUnordered = File.ReadAllText("Examples/Input_Unordered.json"); - transformer = File.ReadAllText("Examples/Transform_Unordered.json"); - transformedString = JsonConvert.SerializeObject - (JsonTransformer.Transform(JObject.Parse(transformer), JObject.Parse(inputUnordered))); - Console.WriteLine(transformedString); - - Console.WriteLine("################################################################################################"); - - string inputUnordered2 = File.ReadAllText("Examples/Input_Unordered_2.json"); - transformer = File.ReadAllText("Examples/Transform_Unordered_2.json"); - transformedString = JsonConvert.SerializeObject - (JsonTransformer.Transform(JObject.Parse(transformer), JObject.Parse(inputUnordered2))); - Console.WriteLine(transformedString); - - Console.WriteLine("################################################################################################"); - - - string inputDyn= File.ReadAllText("Examples/InputDynamic.json"); - transformer = File.ReadAllText("Examples/TransformDynamic.json"); - transformedString = JsonConvert.SerializeObject - (JsonTransformer.Transform(JObject.Parse(transformer), JObject.Parse(inputDyn))); - Console.WriteLine(transformedString); - - Console.WriteLine("################################################################################################"); - - transformer = File.ReadAllText("Examples/Transformer_externalmethods.json"); - transformedString = JsonConvert.SerializeObject - (JsonTransformer.Transform(JObject.Parse(transformer), JObject.Parse(input))); - Console.WriteLine(transformedString); - - Console.WriteLine("################################################################################################"); - - transformer = File.ReadAllText("Examples/Transformer_array.json"); - transformedString = JsonConvert.SerializeObject - (JsonTransformer.Transform(transformer, input)); - Console.WriteLine(transformedString); - - Console.WriteLine("################################################################################################"); - - transformer = File.ReadAllText("Examples/Transformer_array.json"); - transformedString = JsonConvert.SerializeObject - (JsonTransformer.Transform(JArray.Parse(transformer), input)); - Console.WriteLine(transformedString); - - Console.ReadLine(); - } - } -} diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 12206e5..04e13f8 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -28,19 +28,19 @@ steps: - task: NuGetCommand@2 inputs: command: 'restore' - restoreSolution: 'JUST.NET.Test.sln' + restoreSolution: 'JUST.NET.sln' feedsToUse: 'select' vstsFeed: 'f7087ef5-bf6f-48b2-8b8b-5e513f4a7a9e' - task: MSBuild@1 inputs: - solution: 'JUST.NET.Test.sln' + solution: 'JUST.NET.sln' configuration: '$(buildConfiguration)' - task: NuGetCommand@2 inputs: command: 'pack' - packagesToPack: '**/JUST.net.csproj;!**/JUST.NET.Test.csproj' + packagesToPack: '**/JUST.net.csproj;!**/JUST.NET.csproj' configuration: '$(buildConfiguration)' versioningScheme: 'off' From 9179f146b1e70004e8a7fc559e09c907e167e175 Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Thu, 3 Sep 2020 21:56:52 +0200 Subject: [PATCH 20/43] Add unit tests --- JUST.NET.sln | 10 ++++---- JUST.Net.Test/JUST.Net.Test.csproj | 20 ++++++++++++++++ JUST.Net.Test/JsonStaticValueTest.cs | 34 ++++++++++++++++++++++++++++ azure-pipelines.yml | 8 +++++++ 4 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 JUST.Net.Test/JUST.Net.Test.csproj create mode 100644 JUST.Net.Test/JsonStaticValueTest.cs diff --git a/JUST.NET.sln b/JUST.NET.sln index 22b23f2..1e77d31 100644 --- a/JUST.NET.sln +++ b/JUST.NET.sln @@ -13,16 +13,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ENV", "ENV", "{FF566713-3F0 README.md = README.md EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JUST.Net.Test", "JUST.Net.Test\JUST.Net.Test.csproj", "{4D2D7084-412B-4782-A687-BA2C22D3D14B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {507F2FFD-22BD-433E-9CEC-0B210DF18ED3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {507F2FFD-22BD-433E-9CEC-0B210DF18ED3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {507F2FFD-22BD-433E-9CEC-0B210DF18ED3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {507F2FFD-22BD-433E-9CEC-0B210DF18ED3}.Release|Any CPU.Build.0 = Release|Any CPU {C33053BC-A3F2-4F0A-9B7F-B0AF5AD4EFFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C33053BC-A3F2-4F0A-9B7F-B0AF5AD4EFFB}.Debug|Any CPU.Build.0 = Debug|Any CPU {C33053BC-A3F2-4F0A-9B7F-B0AF5AD4EFFB}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -31,6 +29,10 @@ Global {15F60FAC-38CF-4AA7-B369-E738702AA94E}.Debug|Any CPU.Build.0 = Debug|Any CPU {15F60FAC-38CF-4AA7-B369-E738702AA94E}.Release|Any CPU.ActiveCfg = Release|Any CPU {15F60FAC-38CF-4AA7-B369-E738702AA94E}.Release|Any CPU.Build.0 = Release|Any CPU + {4D2D7084-412B-4782-A687-BA2C22D3D14B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4D2D7084-412B-4782-A687-BA2C22D3D14B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4D2D7084-412B-4782-A687-BA2C22D3D14B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4D2D7084-412B-4782-A687-BA2C22D3D14B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/JUST.Net.Test/JUST.Net.Test.csproj b/JUST.Net.Test/JUST.Net.Test.csproj new file mode 100644 index 0000000..83a1c9c --- /dev/null +++ b/JUST.Net.Test/JUST.Net.Test.csproj @@ -0,0 +1,20 @@ + + + + netcoreapp3.1 + + false + + + + + + + + + + + + + + diff --git a/JUST.Net.Test/JsonStaticValueTest.cs b/JUST.Net.Test/JsonStaticValueTest.cs new file mode 100644 index 0000000..134181f --- /dev/null +++ b/JUST.Net.Test/JsonStaticValueTest.cs @@ -0,0 +1,34 @@ +using Newtonsoft.Json.Linq; +using System; +using Xunit; + +namespace JUST.Net.Test +{ + public class JsonStaticValueTest + { + [Fact] + public void Converter_ValueOf_SimpleTest() + { + var input = @"{ ""name"": ""max"" }"; + var transformer = @"{ ""firstName"": ""#valueof($.name)"" }"; + + var result = JsonTransformer.Transform(transformer, input); + + var obj = JObject.Parse(result); + Assert.Equal("max", obj.SelectToken("$.firstName").Value()); + } + + [Fact] + public void Converter_Static_SimpleTest() + { + var input = @"{ ""name"": ""max"" }"; + var transformer = @"{ ""firstName"": ""#valueof($.name)"", ""lastName"": ""max2"" }"; + + var result = JsonTransformer.Transform(transformer, input); + + var obj = JObject.Parse(result); + Assert.Equal("max", obj.SelectToken("$.firstName").Value()); + Assert.Equal("max2", obj.SelectToken("$.lastName").Value()); + } + } +} diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 04e13f8..1539cb5 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -37,6 +37,14 @@ steps: solution: 'JUST.NET.sln' configuration: '$(buildConfiguration)' +- task: DotNetCoreCLI@2 + displayName: 'Run unit tests - $(buildConfiguration)' + inputs: + command: 'test' + arguments: '--configuration $(buildConfiguration) /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput=$(Build.SourcesDirectory)/TestResults/Coverage/' + publishTestResults: true + projects: '**/*.Test.csproj' + - task: NuGetCommand@2 inputs: command: 'pack' From 1596d11f4f335336d0bd897fc1d17ce23be4e529 Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Thu, 3 Sep 2020 22:02:03 +0200 Subject: [PATCH 21/43] Remove not required Exception (ex) --- JUST.Net.Test/DynamicExpressoTest.cs | 23 +++++++++++++++++++++++ JUST.net/JUST.net.csproj | 1 + JUST.net/Transformer.cs | 2 +- 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 JUST.Net.Test/DynamicExpressoTest.cs diff --git a/JUST.Net.Test/DynamicExpressoTest.cs b/JUST.Net.Test/DynamicExpressoTest.cs new file mode 100644 index 0000000..63b40f3 --- /dev/null +++ b/JUST.Net.Test/DynamicExpressoTest.cs @@ -0,0 +1,23 @@ +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace JUST.Net.Test +{ + public class DynamicExpressoTest + { + [Fact] + public void StringConcat_Test() + { + var input = @"{ ""firstName"": ""max"", ""lastName"": ""foo"" }"; + var transformer = @"{ ""friendlyName"": ""~(valueOf(c, ""$.firstName"") + valueOf(c, ""$.lastName""))"" }"; + + var result = JsonTransformer.Transform(transformer, input); + + var obj = JObject.Parse(result); + //Assert.Equal("max foo", obj.SelectToken("$.friendlyName").Value()); + } + } +} diff --git a/JUST.net/JUST.net.csproj b/JUST.net/JUST.net.csproj index fde7be3..ed79800 100644 --- a/JUST.net/JUST.net.csproj +++ b/JUST.net/JUST.net.csproj @@ -28,6 +28,7 @@ https://github.com/WorkMaze/JUST.net/issues/25 + diff --git a/JUST.net/Transformer.cs b/JUST.net/Transformer.cs index 8ceeb16..6dd585b 100644 --- a/JUST.net/Transformer.cs +++ b/JUST.net/Transformer.cs @@ -494,7 +494,7 @@ public static string maxatpath(string array, string jsonPath, string inputJson) return integerresult.ToString(); } - catch(Exception ex) + catch { return null; } From f6c756e2d64c36b235fe0444ba311e84d77c7c08 Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Thu, 3 Sep 2020 22:15:02 +0200 Subject: [PATCH 22/43] Make json transformer none-static --- JUST.Net.Test/DynamicExpressoTest.cs | 8 +++-- JUST.Net.Test/JsonStaticValueTest.cs | 6 ++-- JUST.net/JsonTransformer.cs | 51 ++++++++++++---------------- JUST.net/ReflectionHelper.cs | 19 ----------- 4 files changed, 30 insertions(+), 54 deletions(-) diff --git a/JUST.Net.Test/DynamicExpressoTest.cs b/JUST.Net.Test/DynamicExpressoTest.cs index 63b40f3..bc77ae7 100644 --- a/JUST.Net.Test/DynamicExpressoTest.cs +++ b/JUST.Net.Test/DynamicExpressoTest.cs @@ -12,12 +12,14 @@ public class DynamicExpressoTest public void StringConcat_Test() { var input = @"{ ""firstName"": ""max"", ""lastName"": ""foo"" }"; - var transformer = @"{ ""friendlyName"": ""~(valueOf(c, ""$.firstName"") + valueOf(c, ""$.lastName""))"" }"; + var transformer = @"{ ""friendlyName"": ""~(valueOf(c, \""$.firstName\"") + valueOf(c, \""$.lastName\""))"" }"; - var result = JsonTransformer.Transform(transformer, input); + var jsonTransformer = new JsonTransformer(); + var result = jsonTransformer.Transform(transformer, input); var obj = JObject.Parse(result); - //Assert.Equal("max foo", obj.SelectToken("$.friendlyName").Value()); + // Assert.Equal("max foo", obj.SelectToken("$.friendlyName").Value()); + Assert.True(true); } } } diff --git a/JUST.Net.Test/JsonStaticValueTest.cs b/JUST.Net.Test/JsonStaticValueTest.cs index 134181f..7ea96ba 100644 --- a/JUST.Net.Test/JsonStaticValueTest.cs +++ b/JUST.Net.Test/JsonStaticValueTest.cs @@ -12,7 +12,8 @@ public void Converter_ValueOf_SimpleTest() var input = @"{ ""name"": ""max"" }"; var transformer = @"{ ""firstName"": ""#valueof($.name)"" }"; - var result = JsonTransformer.Transform(transformer, input); + var jsonTransformer = new JsonTransformer(); + var result = jsonTransformer.Transform(transformer, input); var obj = JObject.Parse(result); Assert.Equal("max", obj.SelectToken("$.firstName").Value()); @@ -24,7 +25,8 @@ public void Converter_Static_SimpleTest() var input = @"{ ""name"": ""max"" }"; var transformer = @"{ ""firstName"": ""#valueof($.name)"", ""lastName"": ""max2"" }"; - var result = JsonTransformer.Transform(transformer, input); + var jsonTransformer = new JsonTransformer(); + var result = jsonTransformer.Transform(transformer, input); var obj = JObject.Parse(result); Assert.Equal("max", obj.SelectToken("$.firstName").Value()); diff --git a/JUST.net/JsonTransformer.cs b/JUST.net/JsonTransformer.cs index c1ebf2f..cacbecd 100644 --- a/JUST.net/JsonTransformer.cs +++ b/JUST.net/JsonTransformer.cs @@ -12,10 +12,10 @@ public class JsonTransformer { private const string DefaultTransformerNamespace = "JUST.Transformer"; - public static string Transform(string transformerJson, string inputJson) + public string Transform(string transformerJson, string inputJson) { - JToken result = null; JToken transformerToken = JToken.Parse(transformerJson); + JToken result; switch (transformerToken.Type) { case JTokenType.Object: @@ -33,7 +33,7 @@ public static string Transform(string transformerJson, string inputJson) return output; } - public static JArray Transform(JArray transformerArray, string input) + public JArray Transform(JArray transformerArray, string input) { var result = new JArray(); foreach (var transformer in transformerArray) @@ -48,21 +48,22 @@ public static JArray Transform(JArray transformerArray, string input) return result; } - public static JObject Transform(JObject transformer, JObject input) + public JObject Transform(JObject transformer, JObject input) { string inputJson = JsonConvert.SerializeObject(input); return Transform(transformer, inputJson); } - public static JObject Transform(JObject transformer, string input) + public JObject Transform(JObject transformer, string input) { RecursiveEvaluate(transformer, input, null, null); return transformer; } + #region RecursiveEvaluate - private static void RecursiveEvaluate(JToken parentToken, string inputJson, JArray parentArray, JToken currentArrayToken) + private void RecursiveEvaluate(JToken parentToken, string inputJson, JArray parentArray, JToken currentArrayToken) { if (parentToken == null) return; @@ -255,10 +256,6 @@ private static void RecursiveEvaluate(JToken parentToken, string inputJson, JArr loopProperties.Add(property.Name); } - - - - isLoop = true; } @@ -283,13 +280,13 @@ private static void RecursiveEvaluate(JToken parentToken, string inputJson, JArr int sIndex = strArrayToken.IndexOf("#"); string sub1 = strArrayToken.Substring(0, sIndex); - int indexOfENdFubction = GetIndexOfFunctionEnd(strArrayToken); + int indexOfEndFunction = GetIndexOfFunctionEnd(strArrayToken); - if (indexOfENdFubction > sIndex && sIndex > 0) + if (indexOfEndFunction > sIndex && sIndex > 0) { - string sub2 = strArrayToken.Substring(indexOfENdFubction + 1, strArrayToken.Length - indexOfENdFubction - 1); + string sub2 = strArrayToken.Substring(indexOfEndFunction + 1, strArrayToken.Length - indexOfEndFunction - 1); - string functionResult = ParseFunction(strArrayToken.Substring(sIndex, indexOfENdFubction - sIndex + 1), inputJson, parentArray, currentArrayToken).ToString(); + string functionResult = ParseFunction(strArrayToken.Substring(sIndex, indexOfEndFunction - sIndex + 1), inputJson, parentArray, currentArrayToken).ToString(); strArrayToken = sub1 + functionResult + sub2; } @@ -361,8 +358,6 @@ private static void RecursiveEvaluate(JToken parentToken, string inputJson, JArr if (childToken.Type == JTokenType.String && childToken.Value().Trim().StartsWith("#") && parentArray != null && currentArrayToken != null) { - - object newValue = ParseFunction(childToken.Value(), inputJson, parentArray, currentArrayToken); if (newValue != null && newValue.ToString().Contains("\"")) @@ -480,7 +475,7 @@ private static void RecursiveEvaluate(JToken parentToken, string inputJson, JArr #endregion #region Copy - private static JToken Copy(string inputString, string inputJson) + private JToken Copy(string inputString, string inputJson) { int indexOfStart = inputString.IndexOf("(", 0); int indexOfEnd = inputString.LastIndexOf(")"); @@ -499,7 +494,7 @@ private static JToken Copy(string inputString, string inputJson) #endregion #region Delete - private static string Delete(string inputString) + private string Delete(string inputString) { int indexOfStart = inputString.IndexOf("(", 0); int indexOfEnd = inputString.LastIndexOf(")"); @@ -515,7 +510,7 @@ private static string Delete(string inputString) #endregion #region Replace - private static JToken Replace(string inputString, string inputJson) + private JToken Replace(string inputString, string inputJson) { int indexOfStart = inputString.IndexOf("(", 0); int indexOfEnd = inputString.LastIndexOf(")"); @@ -541,7 +536,7 @@ private static JToken Replace(string inputString, string inputJson) } - private static string GetTokenStringToReplace(string inputString) + private string GetTokenStringToReplace(string inputString) { int indexOfStart = inputString.IndexOf("(", 0); int indexOfEnd = inputString.LastIndexOf(")"); @@ -560,7 +555,7 @@ private static string GetTokenStringToReplace(string inputString) #region ParseFunction - private static object ParseFunction(string functionString, string inputJson, JArray array, JToken currentArrayElement) + private object ParseFunction(string functionString, string inputJson, JArray array, JToken currentArrayElement) { try { @@ -654,10 +649,6 @@ private static object ParseFunction(string functionString, string inputJson, JAr output = ReflectionHelper.InvokeFunction(null, "JUST.Transformer", functionName, new object[] { array, currentArrayElement, arguments[0] }); else if (functionName == "customfunction") output = CallCustomFunction(parameters); - else if (Regex.IsMatch(functionName, ReflectionHelper.EXTERNAL_ASSEMBLY_REGEX)) - { - output = ReflectionHelper.CallExternalAssembly(functionName, parameters); - } else if (functionName == "xconcat" || functionName == "xadd" || functionName == "mathequals" || functionName == "mathgreaterthan" || functionName == "mathlessthan" || functionName == "mathgreaterthanorequalto" @@ -685,7 +676,7 @@ private static object ParseFunction(string functionString, string inputJson, JAr } } - private static object CallCustomFunction(object[] parameters) + private object CallCustomFunction(object[] parameters) { object[] customParameters = new object[parameters.Length - 3]; string functionString = string.Empty; @@ -717,7 +708,7 @@ private static object CallCustomFunction(object[] parameters) #endregion #region GetArguments - private static string[] GetArguments(string rawArgument) + private string[] GetArguments(string rawArgument) { if (rawArgument.Trim() == "") return new string[] { }; @@ -782,7 +773,7 @@ private static string[] GetArguments(string rawArgument) #endregion #region Split - public static IEnumerable SplitJson(string input, string arrayPath) + public IEnumerable SplitJson(string input, string arrayPath) { JObject inputJObject = JObject.Parse(input); @@ -801,7 +792,7 @@ public static IEnumerable SplitJson(string input, string arrayPath) return output; } - public static IEnumerable SplitJson(JObject input, string arrayPath) + public IEnumerable SplitJson(JObject input, string arrayPath) { List jsonObjects = null; @@ -840,7 +831,7 @@ public static IEnumerable SplitJson(JObject input, string arrayPath) } #endregion - private static int GetIndexOfFunctionEnd(string totalString) + private int GetIndexOfFunctionEnd(string totalString) { int index = -1; diff --git a/JUST.net/ReflectionHelper.cs b/JUST.net/ReflectionHelper.cs index 5f8f10b..aa73399 100644 --- a/JUST.net/ReflectionHelper.cs +++ b/JUST.net/ReflectionHelper.cs @@ -10,8 +10,6 @@ namespace JUST { internal class ReflectionHelper { - internal const string EXTERNAL_ASSEMBLY_REGEX = "([\\w.]+)[:]{2}([\\w.]+)[:]{0,2}([\\w.]*)"; - internal static object InvokeFunction(Assembly assembly, String myclass, String mymethod, object[] parameters, bool convertParameters = false) { Type type = assembly?.GetType(myclass) ?? Type.GetType(myclass); @@ -31,23 +29,6 @@ internal static object InvokeFunction(Assembly assembly, String myclass, String return methodInfo.Invoke(instance, convertParameters ? typedParameters.ToArray() : parameters); } - internal static object CallExternalAssembly(string functionName, object[] parameters) - { - var match = Regex.Match(functionName, EXTERNAL_ASSEMBLY_REGEX); - var isAssemblyDefined = match.Groups.Count == 4 && match.Groups[3].Value != string.Empty; - var assemblyName = isAssemblyDefined ? match.Groups[1].Value : null; - var namespc = match.Groups[isAssemblyDefined ? 2 : 1].Value; - var methodName = match.Groups[isAssemblyDefined ? 3 : 2].Value; - - var assembly = GetAssembly(isAssemblyDefined, assemblyName, namespc, methodName); - if (assembly != null) - { - return InvokeFunction(assembly, namespc, methodName, FilterParameters(parameters), true); - } - - throw new MissingMethodException((assemblyName != null ? $"{assemblyName}." : string.Empty) + $"{namespc}.{methodName}"); - } - private static Assembly GetAssembly(bool isAssemblyDefined, string assemblyName, string namespc, string methodName) { var assemblies = AppDomain.CurrentDomain.GetAssemblies(); From ca3aa15b14879c332ec714a59a0aec11d1088a5c Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Thu, 3 Sep 2020 22:26:12 +0200 Subject: [PATCH 23/43] Move not required code --- JUST.net/JsonTransformer.cs | 90 +++++++++++-------------------------- JUST.net/JsonUtilities.cs | 68 ++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 63 deletions(-) create mode 100644 JUST.net/JsonUtilities.cs diff --git a/JUST.net/JsonTransformer.cs b/JUST.net/JsonTransformer.cs index cacbecd..80e0398 100644 --- a/JUST.net/JsonTransformer.cs +++ b/JUST.net/JsonTransformer.cs @@ -12,6 +12,13 @@ public class JsonTransformer { private const string DefaultTransformerNamespace = "JUST.Transformer"; + #region [Transform] + /// + /// Transform json by json as string + /// + /// Transformer as .net string + /// Input as .net string (json) + /// public string Transform(string transformerJson, string inputJson) { JToken transformerToken = JToken.Parse(transformerJson); @@ -33,6 +40,12 @@ public string Transform(string transformerJson, string inputJson) return output; } + /// + /// Transform json array (JArray) + /// + /// Transformer as array + /// Input as .net string (json) + /// Transformed json public JArray Transform(JArray transformerArray, string input) { var result = new JArray(); @@ -48,21 +61,32 @@ public JArray Transform(JArray transformerArray, string input) return result; } + /// + /// Transform JObject by using a JObject transformer + /// + /// Transformer as NewtonsoftJson object + /// Input as Newtonsoft.Json object + /// Transformed json as JObject public JObject Transform(JObject transformer, JObject input) { string inputJson = JsonConvert.SerializeObject(input); return Transform(transformer, inputJson); } + /// + /// Transform json by using a JObject + /// + /// Transformer as JObject + /// Json to transform + /// Transformed JObject public JObject Transform(JObject transformer, string input) { RecursiveEvaluate(transformer, input, null, null); return transformer; } + #endregion #region RecursiveEvaluate - - private void RecursiveEvaluate(JToken parentToken, string inputJson, JArray parentArray, JToken currentArrayToken) { if (parentToken == null) @@ -720,10 +744,9 @@ private string[] GetArguments(string rawArgument) int openBrackettCount = 0; int closebrackettCount = 0; - var currentArgument = ""; - for (int i = 0; i < rawArgument.Length; i++) { + string currentArgument; if (index != 0) currentArgument = rawArgument.Substring(index + 1, i - index - 1); else @@ -772,65 +795,6 @@ private string[] GetArguments(string rawArgument) } #endregion - #region Split - public IEnumerable SplitJson(string input, string arrayPath) - { - JObject inputJObject = JObject.Parse(input); - - List jObjects = SplitJson(inputJObject, arrayPath).ToList(); - - List output = null; - - foreach (JObject jObject in jObjects) - { - if (output == null) - output = new List(); - - output.Add(JsonConvert.SerializeObject(jObject)); - } - - return output; - } - - public IEnumerable SplitJson(JObject input, string arrayPath) - { - List jsonObjects = null; - - JToken tokenArr = input.SelectToken(arrayPath); - - string pathToReplace = tokenArr.Path; - - if (tokenArr != null && tokenArr is JArray) - { - JArray array = tokenArr as JArray; - - foreach (JToken tokenInd in array) - { - - string path = tokenInd.Path; - - JToken clonedToken = input.DeepClone(); - - JToken foundToken = clonedToken.SelectToken("$." + path); - JToken tokenToReplcae = clonedToken.SelectToken("$." + pathToReplace); - - tokenToReplcae.Replace(foundToken); - - if (jsonObjects == null) - jsonObjects = new List(); - - jsonObjects.Add(clonedToken as JObject); - - - } - } - else - throw new Exception("ArrayPath must be a valid JSON path to a JSON array."); - - return jsonObjects; - } - #endregion - private int GetIndexOfFunctionEnd(string totalString) { int index = -1; diff --git a/JUST.net/JsonUtilities.cs b/JUST.net/JsonUtilities.cs new file mode 100644 index 0000000..6e110ff --- /dev/null +++ b/JUST.net/JsonUtilities.cs @@ -0,0 +1,68 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace JUST.net +{ + public static class JsonUtilities + { + public static IEnumerable SplitJson(string input, string arrayPath) + { + JObject inputJObject = JObject.Parse(input); + + List jObjects = SplitJson(inputJObject, arrayPath).ToList(); + + List output = null; + + foreach (JObject jObject in jObjects) + { + if (output == null) + output = new List(); + + output.Add(JsonConvert.SerializeObject(jObject)); + } + + return output; + } + + public static IEnumerable SplitJson(JObject input, string arrayPath) + { + List jsonObjects = null; + + JToken tokenArr = input.SelectToken(arrayPath); + + string pathToReplace = tokenArr.Path; + + if (tokenArr != null && tokenArr is JArray) + { + JArray array = tokenArr as JArray; + + foreach (JToken tokenInd in array) + { + + string path = tokenInd.Path; + + JToken clonedToken = input.DeepClone(); + + JToken foundToken = clonedToken.SelectToken("$." + path); + JToken tokenToReplcae = clonedToken.SelectToken("$." + pathToReplace); + + tokenToReplcae.Replace(foundToken); + + if (jsonObjects == null) + jsonObjects = new List(); + + jsonObjects.Add(clonedToken as JObject); + + + } + } + else + throw new Exception("ArrayPath must be a valid JSON path to a JSON array."); + + return jsonObjects; + } + } +} From c63eb1ce24afb1d19f96dfc870ba802ecf4acb2a Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Thu, 3 Sep 2020 22:41:55 +0200 Subject: [PATCH 24/43] Add basic exprefssion utilities --- JUST.Net.Test/ExpressionParserTest.cs | 47 +++++++++++++++++++++++++++ JUST.net/ExpressionParserUtilities.cs | 35 ++++++++++++++++++++ JUST.net/JsonTransformer.cs | 5 +++ 3 files changed, 87 insertions(+) create mode 100644 JUST.Net.Test/ExpressionParserTest.cs create mode 100644 JUST.net/ExpressionParserUtilities.cs diff --git a/JUST.Net.Test/ExpressionParserTest.cs b/JUST.Net.Test/ExpressionParserTest.cs new file mode 100644 index 0000000..56375cf --- /dev/null +++ b/JUST.Net.Test/ExpressionParserTest.cs @@ -0,0 +1,47 @@ +using JUST.net; +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace JUST.Net.Test +{ + public class ExpressionParserTest + { + [Fact] + public void ExpressionTest_False() + { + var isExpression = ExpressionParserUtilities.IsExpression("~Sample Value", out string expression); + + Assert.False(isExpression); + Assert.Equal("", expression); + } + + [Fact] + public void ExpressionTest_NoNested_False() + { + var isExpression = ExpressionParserUtilities.IsExpression("~Sample ~(some-not-expression) Value", out string expression); + + Assert.False(isExpression); + Assert.Equal("", expression); + } + + [Fact] + public void ExpressionTest_True() + { + var isExpression = ExpressionParserUtilities.IsExpression("~(func(\"Sample Value\"))", out string expression); + + Assert.True(isExpression); + Assert.Equal("func(\"Sample Value\")", expression); + } + + [Fact] + public void ExpressionTest_EmptyExpression_True() + { + var isExpression = ExpressionParserUtilities.IsExpression("~()", out string expression); + + Assert.True(isExpression); + Assert.Equal("", expression); + } + } +} diff --git a/JUST.net/ExpressionParserUtilities.cs b/JUST.net/ExpressionParserUtilities.cs new file mode 100644 index 0000000..738ad8a --- /dev/null +++ b/JUST.net/ExpressionParserUtilities.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace JUST.net +{ + /// + /// Expression utilities + /// + public static class ExpressionParserUtilities + { + /// + /// Checks whether a string represents an expression + /// + /// Json string value + /// If value is an expression, the expression string will be returned as this output parameter + /// True if the input string is an expression + public static bool IsExpression(string value, out string expression) + { + expression = ""; + + if (string.IsNullOrWhiteSpace(value)) + return false; + + var trimmedValue = value.Trim(); + if (trimmedValue.StartsWith("~(") && trimmedValue.EndsWith(")")) + { + expression = trimmedValue.Substring(2, trimmedValue.Length - 3); + return true; + } + + return false; + } + } +} diff --git a/JUST.net/JsonTransformer.cs b/JUST.net/JsonTransformer.cs index 80e0398..1e6ed01 100644 --- a/JUST.net/JsonTransformer.cs +++ b/JUST.net/JsonTransformer.cs @@ -579,6 +579,11 @@ private string GetTokenStringToReplace(string inputString) #region ParseFunction + private object ExecuteExpression(string expression, string inputJson) + { + return null; + } + private object ParseFunction(string functionString, string inputJson, JArray array, JToken currentArrayElement) { try From a5217cc7e1e400a7880894620696b0864a08a4ca Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Fri, 4 Sep 2020 14:26:56 +0200 Subject: [PATCH 25/43] Remove not required transformer functions --- JUST.Net.Test/DynamicExpressoTest.cs | 36 ++++++- JUST.Net.Test/ExpressionParserTest.cs | 3 - JUST.net/JsonTransformer.cs | 72 +++++++------ JUST.net/Transformer.cs | 148 -------------------------- 4 files changed, 73 insertions(+), 186 deletions(-) diff --git a/JUST.Net.Test/DynamicExpressoTest.cs b/JUST.Net.Test/DynamicExpressoTest.cs index bc77ae7..2cd268f 100644 --- a/JUST.Net.Test/DynamicExpressoTest.cs +++ b/JUST.Net.Test/DynamicExpressoTest.cs @@ -9,16 +9,46 @@ namespace JUST.Net.Test public class DynamicExpressoTest { [Fact] - public void StringConcat_Test() + public void StringConcat_Static_Test() { var input = @"{ ""firstName"": ""max"", ""lastName"": ""foo"" }"; - var transformer = @"{ ""friendlyName"": ""~(valueOf(c, \""$.firstName\"") + valueOf(c, \""$.lastName\""))"" }"; + //var transformer = @"{ ""friendlyName"": ""~(valueOf(c, \""$.firstName\"") + valueOf(c, \""$.lastName\""))"" }"; + var transformer = @"{ ""friendlyName"": ""~(\""max\"" + \"" \"" + \""foo\"")"" }"; var jsonTransformer = new JsonTransformer(); var result = jsonTransformer.Transform(transformer, input); var obj = JObject.Parse(result); - // Assert.Equal("max foo", obj.SelectToken("$.friendlyName").Value()); + Assert.Equal("max foo", obj.SelectToken("$.friendlyName").Value()); + Assert.True(true); + } + + [Fact] + public void String_ValueOf_Test() + { + var input = @"{ ""firstName"": ""max"" }"; + //var transformer = @"{ ""friendlyName"": ""~(valueOf(c, \""$.firstName\"") + valueOf(c, \""$.lastName\""))"" }"; + var transformer = @"{ ""friendlyName"": ""~(valueOf(\""$.firstName\""))"" }"; + + var jsonTransformer = new JsonTransformer(); + var result = jsonTransformer.Transform(transformer, input); + + var obj = JObject.Parse(result); + Assert.Equal("max", obj.SelectToken("$.friendlyName").Value()); + Assert.True(true); + } + + [Fact] + public void String_ValueOf_Concat_Test() + { + var input = @"{ ""firstName"": ""max"", ""lastName"": ""foo"" }"; + var transformer = @"{ ""friendlyName"": ""~(valueOfStr(\""$.firstName\"") + valueOfStr(\""$.lastName\""))"" }"; + + var jsonTransformer = new JsonTransformer(); + var result = jsonTransformer.Transform(transformer, input); + + var obj = JObject.Parse(result); + Assert.Equal("maxfoo", obj.SelectToken("$.friendlyName").Value()); Assert.True(true); } } diff --git a/JUST.Net.Test/ExpressionParserTest.cs b/JUST.Net.Test/ExpressionParserTest.cs index 56375cf..612c6ab 100644 --- a/JUST.Net.Test/ExpressionParserTest.cs +++ b/JUST.Net.Test/ExpressionParserTest.cs @@ -1,7 +1,4 @@ using JUST.net; -using System; -using System.Collections.Generic; -using System.Text; using Xunit; namespace JUST.Net.Test diff --git a/JUST.net/JsonTransformer.cs b/JUST.net/JsonTransformer.cs index 1e6ed01..ca0bbb4 100644 --- a/JUST.net/JsonTransformer.cs +++ b/JUST.net/JsonTransformer.cs @@ -1,4 +1,5 @@ -using Newtonsoft.Json; +using JUST.net; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; @@ -182,28 +183,44 @@ private void RecursiveEvaluate(JToken parentToken, string inputJson, JArray pare } - if (property.Name != null && property.Value.ToString().Trim().StartsWith("#") - && !property.Name.Contains("#eval") && !property.Name.Contains("#ifgroup") - && !property.Name.Contains("#loop")) + if (ExpressionParserUtilities.IsExpression(property.Value.ToString().Trim(), out string expression)) { - object newValue = ParseFunction(property.Value.ToString(), inputJson, parentArray, currentArrayToken); + // Create context - if (newValue != null && newValue.ToString().Contains("\"")) - { - try - { - JToken newToken = JToken.Parse(newValue.ToString()); - property.Value = newToken; - } - catch - { - property.Value = new JValue(newValue); - } - } - else - property.Value = new JValue(newValue); + var interpreter = new DynamicExpresso.Interpreter(); + + Func valueOf = (path) => Transformer.valueof(path, inputJson).ToString(); + + interpreter.SetFunction("valueOfStr", valueOf); + + var result = interpreter.Eval(expression); + + property.Value = new JValue(result); } + // TODO: Not required anymore + // if (property.Name != null && property.Value.ToString().Trim().StartsWith("#") + // && !property.Name.Contains("#eval") && !property.Name.Contains("#ifgroup") + // && !property.Name.Contains("#loop")) + // { + // object newValue = ParseFunction(property.Value.ToString(), inputJson, parentArray, currentArrayToken); + // + // if (newValue != null && newValue.ToString().Contains("\"")) + // { + // try + // { + // JToken newToken = JToken.Parse(newValue.ToString()); + // property.Value = newToken; + // } + // catch + // { + // property.Value = new JValue(newValue); + // } + // } + // else + // property.Value = new JValue(newValue); + // } + /* For looping*/ isLoop = false; @@ -225,9 +242,10 @@ private void RecursiveEvaluate(JToken parentToken, string inputJson, JArray pare if (tokensToAdd == null) { - tokensToAdd = new List(); - - tokensToAdd.Add(clonedProperty); + tokensToAdd = new List + { + clonedProperty + }; } @@ -678,16 +696,6 @@ private object ParseFunction(string functionString, string inputJson, JArray arr output = ReflectionHelper.InvokeFunction(null, "JUST.Transformer", functionName, new object[] { array, currentArrayElement, arguments[0] }); else if (functionName == "customfunction") output = CallCustomFunction(parameters); - else if (functionName == "xconcat" || functionName == "xadd" - || functionName == "mathequals" || functionName == "mathgreaterthan" || functionName == "mathlessthan" - || functionName == "mathgreaterthanorequalto" - || functionName == "mathlessthanorequalto" || functionName == "stringcontains" || - functionName == "stringequals") - { - object[] oParams = new object[1]; - oParams[0] = parameters; - output = ReflectionHelper.InvokeFunction(null, DefaultTransformerNamespace, functionName, oParams); - } else { if (currentArrayElement != null && functionName != "valueof") diff --git a/JUST.net/Transformer.cs b/JUST.net/Transformer.cs index 6dd585b..f259796 100644 --- a/JUST.net/Transformer.cs +++ b/JUST.net/Transformer.cs @@ -89,12 +89,6 @@ public static object ifcondition(object condition, object value, object trueResu #region string functions - public static string concat(string string1, string string2, string inputJson) - { - string string2Result = (string2 != null) ? string2 : string.Empty; - return string1 != null ? string1 + string2Result : string.Empty + string2Result; - } - /// /// Compare to values /// @@ -638,34 +632,6 @@ public static string constant_hash(string inputJson) #endregion - #region Variable parameter functions - public static string xconcat(object[] list) - { - string result = string.Empty; - - for (int i = 0; i < list.Length - 1; i++) - { - if (list[i] != null) - result += list[i].ToString(); - } - - return result; - } - - public static string xadd(object[] list) - { - int add = 0; - - for (int i = 0; i < list.Length - 1; i++) - { - if (list[i] != null) - add += Convert.ToInt32(list[i]); - } - - return add.ToString(); - } - #endregion - public static object GetValue(JToken selectedToken) { object output = null; @@ -732,119 +698,5 @@ public static object grouparrayby(string jsonPath, string groupingElement, strin } #endregion - - #region operators - public static string stringequals(object[] list) - { - bool result = false; - - if (list.Length >= 2) - { - if (list[0].ToString().Equals(list[1].ToString())) - result = true; - } - - return result.ToString(); - } - - public static string stringcontains(object[] list) - { - bool result = false; - - if (list.Length >= 2) - { - if (list[0].ToString().Contains(list[1].ToString())) - result = true; - } - - return result.ToString(); - } - - public static string mathequals(object[] list) - { - bool result = false; - - - if (list.Length >= 2) - { - decimal lshDecimal = Convert.ToDecimal(list[0]); - decimal rhsDecimal = Convert.ToDecimal(list[1]); - - if (lshDecimal == rhsDecimal) - result = true; - } - - return result.ToString(); - } - - public static string mathgreaterthan(object[] list) - { - bool result = false; - - - if (list.Length >= 2) - { - decimal lshDecimal = Convert.ToDecimal(list[0]); - decimal rhsDecimal = Convert.ToDecimal(list[1]); - - if (lshDecimal > rhsDecimal) - result = true; - } - - return result.ToString(); - } - - public static string mathlessthan(object[] list) - { - bool result = false; - - - if (list.Length >= 2) - { - decimal lshDecimal = Convert.ToDecimal(list[0]); - decimal rhsDecimal = Convert.ToDecimal(list[1]); - - if (lshDecimal < rhsDecimal) - result = true; - } - - return result.ToString(); - } - - public static string mathgreaterthanorequalto(object[] list) - { - bool result = false; - - - if (list.Length >= 2) - { - decimal lshDecimal = Convert.ToDecimal(list[0]); - decimal rhsDecimal = Convert.ToDecimal(list[1]); - - if (lshDecimal >= rhsDecimal) - result = true; - } - - return result.ToString(); - } - - public static string mathlessthanorequalto(object[] list) - { - bool result = false; - - - if (list.Length >= 2) - { - decimal lshDecimal = Convert.ToDecimal(list[0]); - decimal rhsDecimal = Convert.ToDecimal(list[1]); - - if (lshDecimal <= rhsDecimal) - result = true; - } - - return result.ToString(); - } - #endregion - } } From cbaceee0da2c0e255c2734ecaa18c73cf4162835 Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Sat, 5 Sep 2020 13:32:50 +0200 Subject: [PATCH 26/43] Add dynamic --- JUST.Net.Test/DynamicObjectExpressionTest.cs | 25 ++++++++++++++++++++ JUST.net/JUST.net.csproj | 2 +- JUST.net/JsonTransformer.cs | 9 ++++--- JUST.net/Transformer.cs | 6 +++-- 4 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 JUST.Net.Test/DynamicObjectExpressionTest.cs diff --git a/JUST.Net.Test/DynamicObjectExpressionTest.cs b/JUST.Net.Test/DynamicObjectExpressionTest.cs new file mode 100644 index 0000000..50b0588 --- /dev/null +++ b/JUST.Net.Test/DynamicObjectExpressionTest.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace JUST.Net.Test +{ + public class DynamicObjectExpressionTest + { + [Fact] + public void String_DynamicVAlue_Concat_Test() + { + var input = @"{ ""firstName"": ""max"", ""lastName"": ""foo"" }"; + var transformer = @"{ ""friendlyName"": ""~(input.firstName + input.lastName)"" }"; + + var jsonTransformer = new JsonTransformer(); + var result = jsonTransformer.Transform(transformer, input); + + var obj = JObject.Parse(result); + Assert.Equal("maxfoo", obj.SelectToken("$.friendlyName").Value()); + Assert.True(true); + } + } +} diff --git a/JUST.net/JUST.net.csproj b/JUST.net/JUST.net.csproj index ed79800..7db0f7c 100644 --- a/JUST.net/JUST.net.csproj +++ b/JUST.net/JUST.net.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + netstandard2.1 This a cool .NET Standard library which enables you to transform a JSON document into another JSON document using JSON transformations using JSON path. This is the JSON equivalent of XSLT. This will repace the JUST and JUST.NETCore packages. https://github.com/WorkMaze/JUST.net diff --git a/JUST.net/JsonTransformer.cs b/JUST.net/JsonTransformer.cs index ca0bbb4..48fe158 100644 --- a/JUST.net/JsonTransformer.cs +++ b/JUST.net/JsonTransformer.cs @@ -12,6 +12,7 @@ namespace JUST public class JsonTransformer { private const string DefaultTransformerNamespace = "JUST.Transformer"; + private object inputObject; #region [Transform] /// @@ -82,6 +83,8 @@ public JObject Transform(JObject transformer, JObject input) /// Transformed JObject public JObject Transform(JObject transformer, string input) { + inputObject = JsonConvert.DeserializeObject(input); + RecursiveEvaluate(transformer, input, null, null); return transformer; } @@ -188,6 +191,7 @@ private void RecursiveEvaluate(JToken parentToken, string inputJson, JArray pare // Create context var interpreter = new DynamicExpresso.Interpreter(); + interpreter.SetVariable("input", inputObject); Func valueOf = (path) => Transformer.valueof(path, inputJson).ToString(); @@ -597,11 +601,6 @@ private string GetTokenStringToReplace(string inputString) #region ParseFunction - private object ExecuteExpression(string expression, string inputJson) - { - return null; - } - private object ParseFunction(string functionString, string inputJson, JArray array, JToken currentArrayElement) { try diff --git a/JUST.net/Transformer.cs b/JUST.net/Transformer.cs index f259796..809ff80 100644 --- a/JUST.net/Transformer.cs +++ b/JUST.net/Transformer.cs @@ -30,8 +30,10 @@ public static string tostring(object input, string inputJson) public static object getarray(string document, string jsonPath, string inputJson) { - JsonReader reader = new JsonTextReader(new StringReader(document)); - reader.DateParseHandling = DateParseHandling.None; + JsonReader reader = new JsonTextReader(new StringReader(document)) + { + DateParseHandling = DateParseHandling.None + }; JToken token = JObject.Load(reader); var jsonArrayToken = token.SelectTokens(jsonPath).ToList(); From 395b7ed1737f8b295999a2e05af31e9a6ae53461 Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Sat, 5 Sep 2020 14:09:00 +0200 Subject: [PATCH 27/43] Add array element at --- .../DynamicExpressionDateTimeTest.cs | 39 ++++++++++ JUST.Net.Test/DynamicExpressoArrayTest.cs | 27 +++++++ JUST.Net.Test/DynamicExpressoTest.cs | 14 ++++ JUST.Net.Test/DynamicObjectExpressionTest.cs | 25 ------- JUST.net/ExpressionInterpreter.cs | 72 +++++++++++++++++++ JUST.net/JUST.net.csproj | 6 +- JUST.net/JsonTransformer.cs | 38 +++++----- JUST.net/Transformer.cs | 8 +-- 8 files changed, 179 insertions(+), 50 deletions(-) create mode 100644 JUST.Net.Test/DynamicExpressionDateTimeTest.cs create mode 100644 JUST.Net.Test/DynamicExpressoArrayTest.cs delete mode 100644 JUST.Net.Test/DynamicObjectExpressionTest.cs create mode 100644 JUST.net/ExpressionInterpreter.cs diff --git a/JUST.Net.Test/DynamicExpressionDateTimeTest.cs b/JUST.Net.Test/DynamicExpressionDateTimeTest.cs new file mode 100644 index 0000000..a652c02 --- /dev/null +++ b/JUST.Net.Test/DynamicExpressionDateTimeTest.cs @@ -0,0 +1,39 @@ +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace JUST.Net.Test +{ + public class DynamicExpressionDateTimeTest + { + [Fact] + public void DateTime_Test() + { + var input = @"{ }"; + var transformer = @"{ ""dt"": ""~(DateTime.Now.Date)"" }"; + + var jsonTransformer = new JsonTransformer(); + var result = jsonTransformer.Transform(transformer, input); + + var obj = JObject.Parse(result); + Assert.Equal(DateTime.Now.Date, obj.SelectToken("$.dt").Value()); + Assert.True(true); + } + + [Fact] + public void DateTime_Format_Test() + { + var input = @"{ }"; + var transformer = @"{ ""dt"": ""~(DateTime.Now.ToString(\""ddMMyyyy\""))"" }"; + + var jsonTransformer = new JsonTransformer(); + var result = jsonTransformer.Transform(transformer, input); + + var obj = JObject.Parse(result); + Assert.Equal(DateTime.Now.ToString("ddMMyyyy"), obj.SelectToken("$.dt").Value()); + Assert.True(true); + } + } +} diff --git a/JUST.Net.Test/DynamicExpressoArrayTest.cs b/JUST.Net.Test/DynamicExpressoArrayTest.cs new file mode 100644 index 0000000..7b994e9 --- /dev/null +++ b/JUST.Net.Test/DynamicExpressoArrayTest.cs @@ -0,0 +1,27 @@ +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace JUST.Net.Test +{ + public class DynamicExpressoArrayTest + { + [Fact] + public void Array_ValueOf_Object_Test() + { + var input = @"{ ""array"": [ { ""name"": ""hans"" }, { ""name"": ""simplic"" } ] }"; + + var transformer = @"{ ""ar"": { ""#loop($.array)"": { ""n"": ""~(valueOfIterStr(\""$.name\""))"" } } }"; + + var jsonTransformer = new JsonTransformer(); + var result = jsonTransformer.Transform(transformer, input); + + var obj = JObject.Parse(result); + Assert.Equal("hans", obj.SelectToken("$.ar[0].n").Value()); + Assert.Equal("simplic", obj.SelectToken("$.ar[1].n").Value()); + Assert.True(true); + } + } +} diff --git a/JUST.Net.Test/DynamicExpressoTest.cs b/JUST.Net.Test/DynamicExpressoTest.cs index 2cd268f..93e6ffb 100644 --- a/JUST.Net.Test/DynamicExpressoTest.cs +++ b/JUST.Net.Test/DynamicExpressoTest.cs @@ -51,5 +51,19 @@ public void String_ValueOf_Concat_Test() Assert.Equal("maxfoo", obj.SelectToken("$.friendlyName").Value()); Assert.True(true); } + + [Fact] + public void String_ValueOf_Add_Test() + { + var input = @"{ ""val1"": 1, ""val2"": ""3"" }"; + var transformer = @"{ ""val"": ""~(valueOfInt(\""$.val1\"") + valueOfInt(\""$.val2\""))"" }"; + + var jsonTransformer = new JsonTransformer(); + var result = jsonTransformer.Transform(transformer, input); + + var obj = JObject.Parse(result); + Assert.Equal("4", obj.SelectToken("$.val").Value()); + Assert.True(true); + } } } diff --git a/JUST.Net.Test/DynamicObjectExpressionTest.cs b/JUST.Net.Test/DynamicObjectExpressionTest.cs deleted file mode 100644 index 50b0588..0000000 --- a/JUST.Net.Test/DynamicObjectExpressionTest.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Text; -using Xunit; - -namespace JUST.Net.Test -{ - public class DynamicObjectExpressionTest - { - [Fact] - public void String_DynamicVAlue_Concat_Test() - { - var input = @"{ ""firstName"": ""max"", ""lastName"": ""foo"" }"; - var transformer = @"{ ""friendlyName"": ""~(input.firstName + input.lastName)"" }"; - - var jsonTransformer = new JsonTransformer(); - var result = jsonTransformer.Transform(transformer, input); - - var obj = JObject.Parse(result); - Assert.Equal("maxfoo", obj.SelectToken("$.friendlyName").Value()); - Assert.True(true); - } - } -} diff --git a/JUST.net/ExpressionInterpreter.cs b/JUST.net/ExpressionInterpreter.cs new file mode 100644 index 0000000..cee295f --- /dev/null +++ b/JUST.net/ExpressionInterpreter.cs @@ -0,0 +1,72 @@ +using DynamicExpresso; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Text; + +namespace JUST.net +{ + /// + /// JUST expresso interprter implementation + /// + internal class ExpressionInterpreter : Interpreter + { + /// + /// Initialize interpreter + /// + public ExpressionInterpreter() + { + // Add references + Reference(typeof(DateTime)); + Reference(typeof(String)); + } + + /// + /// Initialize core methods + /// + public void Setup(JToken inputObject) + { + Func valueOfStr = (path) => Transformer.valueof(path, inputObject).ToString(); + Func valueOf = (path) => Transformer.valueof(path, inputObject); + Func valueOfInt = (path) => + { + int.TryParse(Transformer.valueof(path, inputObject)?.ToString(), out int r); + return r; + }; + Func valueOfDouble = (path) => + { + double.TryParse(Transformer.valueof(path, inputObject)?.ToString(), out double r); + return r; + }; + + SetFunction("valueOf", valueOf); + SetFunction("valueOfStr", valueOfStr); + SetFunction("valueOfInt", valueOfInt); + SetFunction("valueOfDouble", valueOfDouble); + } + + /// + /// Initialize core methods + /// + public void SetContext(JToken arrayElement) + { + Func valueOfStr = (path) => Transformer.valueof(path, arrayElement).ToString(); + Func valueOf = (path) => Transformer.valueof(path, arrayElement); + Func valueOfInt = (path) => + { + int.TryParse(Transformer.valueof(path, arrayElement)?.ToString(), out int r); + return r; + }; + Func valueOfDouble = (path) => + { + double.TryParse(Transformer.valueof(path, arrayElement)?.ToString(), out double r); + return r; + }; + + SetFunction("valueOfIter", valueOf); + SetFunction("valueOfIterStr", valueOfStr); + SetFunction("valueOfIterInt", valueOfInt); + SetFunction("valueOfIterDouble", valueOfDouble); + } + } +} diff --git a/JUST.net/JUST.net.csproj b/JUST.net/JUST.net.csproj index 7db0f7c..4e116f0 100644 --- a/JUST.net/JUST.net.csproj +++ b/JUST.net/JUST.net.csproj @@ -14,9 +14,9 @@ This will repace the JUST and JUST.NETCore packages. Fixed the following issues:- https://github.com/WorkMaze/JUST.net/issues/26 https://github.com/WorkMaze/JUST.net/issues/25 - 5.6.20.825 - 5.6.20.825 - 5.6.20 + 5.7.20.825 + 5.7.20.825 + 5.7.20 diff --git a/JUST.net/JsonTransformer.cs b/JUST.net/JsonTransformer.cs index 48fe158..4784c03 100644 --- a/JUST.net/JsonTransformer.cs +++ b/JUST.net/JsonTransformer.cs @@ -11,8 +11,21 @@ namespace JUST { public class JsonTransformer { + #region Fields private const string DefaultTransformerNamespace = "JUST.Transformer"; - private object inputObject; + private readonly ExpressionInterpreter expressionInterpreter; + private JToken inputObject; + #endregion + + #region Constructor + /// + /// Initialize json transformer + /// + public JsonTransformer() + { + expressionInterpreter = new ExpressionInterpreter(); + } + #endregion #region [Transform] /// @@ -83,7 +96,11 @@ public JObject Transform(JObject transformer, JObject input) /// Transformed JObject public JObject Transform(JObject transformer, string input) { - inputObject = JsonConvert.DeserializeObject(input); + JsonReader reader = new JsonTextReader(new StringReader(input)); + reader.DateParseHandling = DateParseHandling.None; + inputObject = JObject.Load(reader); + + expressionInterpreter.Setup(inputObject); RecursiveEvaluate(transformer, input, null, null); return transformer; @@ -179,8 +196,6 @@ private void RecursiveEvaluate(JToken parentToken, string inputJson, JArray pare tokensToDelete.Add(Delete(arrayValue.Value())); - - } } @@ -189,15 +204,9 @@ private void RecursiveEvaluate(JToken parentToken, string inputJson, JArray pare if (ExpressionParserUtilities.IsExpression(property.Value.ToString().Trim(), out string expression)) { // Create context + expressionInterpreter.SetContext(currentArrayToken); - var interpreter = new DynamicExpresso.Interpreter(); - interpreter.SetVariable("input", inputObject); - - Func valueOf = (path) => Transformer.valueof(path, inputJson).ToString(); - - interpreter.SetFunction("valueOfStr", valueOf); - - var result = interpreter.Eval(expression); + var result = expressionInterpreter.Eval(expression); property.Value = new JValue(result); } @@ -251,9 +260,6 @@ private void RecursiveEvaluate(JToken parentToken, string inputJson, JArray pare clonedProperty }; } - - - } if (property.Name != null && property.Name.Contains("#ifgroup")) @@ -685,7 +691,7 @@ private object ParseFunction(string functionString, string inputJson, JArray arr newArray.Add(arrayItem); } - + output = newArray; } else if (functionName == "currentvalue" || functionName == "currentindex" || functionName == "lastindex" diff --git a/JUST.net/Transformer.cs b/JUST.net/Transformer.cs index 809ff80..bfef2d4 100644 --- a/JUST.net/Transformer.cs +++ b/JUST.net/Transformer.cs @@ -8,13 +8,9 @@ namespace JUST { internal class Transformer { - public static object valueof(string jsonPath, string inputJson) + public static object valueof(string jsonPath, JToken input) { - JsonReader reader = new JsonTextReader(new StringReader(inputJson)); - reader.DateParseHandling = DateParseHandling.None; - JToken token = JObject.Load(reader); - - JToken selectedToken = token.SelectToken(jsonPath); + JToken selectedToken = input.SelectToken(jsonPath); return GetValue(selectedToken); } From 4af24688f916440ee0b062cd2123b4ff23e6effb Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Sat, 5 Sep 2020 14:13:12 +0200 Subject: [PATCH 28/43] Remove old tests --- JUST.Net.Test/JsonStaticValueTest.cs | 36 ---------------------------- 1 file changed, 36 deletions(-) delete mode 100644 JUST.Net.Test/JsonStaticValueTest.cs diff --git a/JUST.Net.Test/JsonStaticValueTest.cs b/JUST.Net.Test/JsonStaticValueTest.cs deleted file mode 100644 index 7ea96ba..0000000 --- a/JUST.Net.Test/JsonStaticValueTest.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Newtonsoft.Json.Linq; -using System; -using Xunit; - -namespace JUST.Net.Test -{ - public class JsonStaticValueTest - { - [Fact] - public void Converter_ValueOf_SimpleTest() - { - var input = @"{ ""name"": ""max"" }"; - var transformer = @"{ ""firstName"": ""#valueof($.name)"" }"; - - var jsonTransformer = new JsonTransformer(); - var result = jsonTransformer.Transform(transformer, input); - - var obj = JObject.Parse(result); - Assert.Equal("max", obj.SelectToken("$.firstName").Value()); - } - - [Fact] - public void Converter_Static_SimpleTest() - { - var input = @"{ ""name"": ""max"" }"; - var transformer = @"{ ""firstName"": ""#valueof($.name)"", ""lastName"": ""max2"" }"; - - var jsonTransformer = new JsonTransformer(); - var result = jsonTransformer.Transform(transformer, input); - - var obj = JObject.Parse(result); - Assert.Equal("max", obj.SelectToken("$.firstName").Value()); - Assert.Equal("max2", obj.SelectToken("$.lastName").Value()); - } - } -} From bd81a909449525932256e60e9aefeaf69cfcad72 Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Sat, 5 Sep 2020 14:17:31 +0200 Subject: [PATCH 29/43] Change net standard version --- JUST.net/ExpressionInterpreter.cs | 2 ++ JUST.net/JUST.net.csproj | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/JUST.net/ExpressionInterpreter.cs b/JUST.net/ExpressionInterpreter.cs index cee295f..7cb2c09 100644 --- a/JUST.net/ExpressionInterpreter.cs +++ b/JUST.net/ExpressionInterpreter.cs @@ -38,11 +38,13 @@ public void Setup(JToken inputObject) double.TryParse(Transformer.valueof(path, inputObject)?.ToString(), out double r); return r; }; + Func nullToString = (value) => value ?? ""; SetFunction("valueOf", valueOf); SetFunction("valueOfStr", valueOfStr); SetFunction("valueOfInt", valueOfInt); SetFunction("valueOfDouble", valueOfDouble); + SetFunction("nullToString", nullToString); } /// diff --git a/JUST.net/JUST.net.csproj b/JUST.net/JUST.net.csproj index 4e116f0..1dadbe2 100644 --- a/JUST.net/JUST.net.csproj +++ b/JUST.net/JUST.net.csproj @@ -1,7 +1,7 @@  - netstandard2.1 + netstandard2.0 This a cool .NET Standard library which enables you to transform a JSON document into another JSON document using JSON transformations using JSON path. This is the JSON equivalent of XSLT. This will repace the JUST and JUST.NETCore packages. https://github.com/WorkMaze/JUST.net @@ -14,9 +14,9 @@ This will repace the JUST and JUST.NETCore packages. Fixed the following issues:- https://github.com/WorkMaze/JUST.net/issues/26 https://github.com/WorkMaze/JUST.net/issues/25 - 5.7.20.825 - 5.7.20.825 - 5.7.20 + 5.8.20.825 + 5.8.20.825 + 5.8.20 From e2f76aed97e418b220ed63e5bb0d2419b73a0df3 Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Sat, 5 Sep 2020 14:30:50 +0200 Subject: [PATCH 30/43] Add convert --- JUST.net/ExpressionInterpreter.cs | 1 + JUST.net/JUST.net.csproj | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/JUST.net/ExpressionInterpreter.cs b/JUST.net/ExpressionInterpreter.cs index 7cb2c09..82b9b47 100644 --- a/JUST.net/ExpressionInterpreter.cs +++ b/JUST.net/ExpressionInterpreter.cs @@ -19,6 +19,7 @@ public ExpressionInterpreter() // Add references Reference(typeof(DateTime)); Reference(typeof(String)); + Reference(typeof(Convert)); } /// diff --git a/JUST.net/JUST.net.csproj b/JUST.net/JUST.net.csproj index 1dadbe2..fdfddf1 100644 --- a/JUST.net/JUST.net.csproj +++ b/JUST.net/JUST.net.csproj @@ -14,9 +14,9 @@ This will repace the JUST and JUST.NETCore packages. Fixed the following issues:- https://github.com/WorkMaze/JUST.net/issues/26 https://github.com/WorkMaze/JUST.net/issues/25 - 5.8.20.825 - 5.8.20.825 - 5.8.20 + 5.8.120.825 + 5.8.120.825 + 5.8.120 From d97c1f516717e3fdafb37bc9c3028dfdac2c893a Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Sat, 5 Sep 2020 16:34:25 +0200 Subject: [PATCH 31/43] Add formatting --- JUST.net/JUST.net.csproj | 6 +++--- JUST.net/JsonTransformer.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/JUST.net/JUST.net.csproj b/JUST.net/JUST.net.csproj index fdfddf1..fcf4f59 100644 --- a/JUST.net/JUST.net.csproj +++ b/JUST.net/JUST.net.csproj @@ -14,9 +14,9 @@ This will repace the JUST and JUST.NETCore packages. Fixed the following issues:- https://github.com/WorkMaze/JUST.net/issues/26 https://github.com/WorkMaze/JUST.net/issues/25 - 5.8.120.825 - 5.8.120.825 - 5.8.120 + 5.8.220.825 + 5.8.220.825 + 5.8.220 diff --git a/JUST.net/JsonTransformer.cs b/JUST.net/JsonTransformer.cs index 4784c03..98db814 100644 --- a/JUST.net/JsonTransformer.cs +++ b/JUST.net/JsonTransformer.cs @@ -50,7 +50,7 @@ public string Transform(string transformerJson, string inputJson) throw new NotSupportedException($"Transformer of type '{transformerToken.Type}' not supported!"); } - string output = JsonConvert.SerializeObject(result); + string output = JsonConvert.SerializeObject(result, Formatting.Indented); return output; } From fd9bd45e4d4ac7698b024303462e637015557ede Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Sat, 5 Sep 2020 17:22:31 +0200 Subject: [PATCH 32/43] Add expression exception --- JUST.net/Exception/ExpressionException.cs | 26 +++++++++++++++++++++++ JUST.net/JUST.net.csproj | 6 +++--- JUST.net/JsonTransformer.cs | 15 +++++++------ JUST.net/Transformer.cs | 7 ------ 4 files changed, 38 insertions(+), 16 deletions(-) create mode 100644 JUST.net/Exception/ExpressionException.cs diff --git a/JUST.net/Exception/ExpressionException.cs b/JUST.net/Exception/ExpressionException.cs new file mode 100644 index 0000000..900afa2 --- /dev/null +++ b/JUST.net/Exception/ExpressionException.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; +using System.Text; + +namespace JUST.net +{ + public class ExpressionException : Exception + { + public ExpressionException() + { + } + + public ExpressionException(string message) : base(message) + { + } + + public ExpressionException(string message, Exception innerException) : base(message, innerException) + { + } + + protected ExpressionException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } +} diff --git a/JUST.net/JUST.net.csproj b/JUST.net/JUST.net.csproj index fcf4f59..d2a1e7e 100644 --- a/JUST.net/JUST.net.csproj +++ b/JUST.net/JUST.net.csproj @@ -14,9 +14,9 @@ This will repace the JUST and JUST.NETCore packages. Fixed the following issues:- https://github.com/WorkMaze/JUST.net/issues/26 https://github.com/WorkMaze/JUST.net/issues/25 - 5.8.220.825 - 5.8.220.825 - 5.8.220 + 5.8.320.825 + 5.8.320.825 + 5.8.320 diff --git a/JUST.net/JsonTransformer.cs b/JUST.net/JsonTransformer.cs index 98db814..1285597 100644 --- a/JUST.net/JsonTransformer.cs +++ b/JUST.net/JsonTransformer.cs @@ -194,21 +194,24 @@ private void RecursiveEvaluate(JToken parentToken, string inputJson, JArray pare if (tokensToDelete == null) tokensToDelete = new List(); - tokensToDelete.Add(Delete(arrayValue.Value())); } } - } if (ExpressionParserUtilities.IsExpression(property.Value.ToString().Trim(), out string expression)) { - // Create context expressionInterpreter.SetContext(currentArrayToken); - var result = expressionInterpreter.Eval(expression); - - property.Value = new JValue(result); + try + { + var result = expressionInterpreter.Eval(expression); + property.Value = new JValue(result); + } + catch (Exception ex) + { + throw new Exception($"Could not execute expression: {expression}", ex); + } } // TODO: Not required anymore diff --git a/JUST.net/Transformer.cs b/JUST.net/Transformer.cs index bfef2d4..ccb6fc9 100644 --- a/JUST.net/Transformer.cs +++ b/JUST.net/Transformer.cs @@ -19,11 +19,6 @@ public static string getcurrentscopeasstring(string inputJson) return inputJson; } - public static string tostring(object input, string inputJson) - { - return input?.ToString(); - } - public static object getarray(string document, string jsonPath, string inputJson) { JsonReader reader = new JsonTextReader(new StringReader(document)) @@ -635,12 +630,10 @@ public static object GetValue(JToken selectedToken) object output = null; if (selectedToken != null) { - if (selectedToken.Type == JTokenType.Date) { DateTime value = Convert.ToDateTime(selectedToken.Value()); - output = value.ToString("yyyy-MM-ddTHH:mm:sszzzz"); } else From 96e61438d7e91dbdac53d161f3394742840eb4a0 Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Sun, 6 Sep 2020 01:43:00 +0200 Subject: [PATCH 33/43] Add currentIndex --- JUST.Net.Test/DynamicExpressoArrayTest.cs | 5 +- JUST.Net.Test/PathNotExistsTest.cs | 84 +++++++++++++++++++++ JUST.net/Exception/ExpressionException.cs | 2 +- JUST.net/Exception/PathNotFoundException.cs | 26 +++++++ JUST.net/ExpressionInterpreter.cs | 49 +++++++++--- JUST.net/JUST.net.csproj | 6 +- JUST.net/JsonTransformer.cs | 16 +++- JUST.net/Transformer.cs | 84 ++++++++++----------- JUST.net/Utilities.cs | 4 +- 9 files changed, 213 insertions(+), 63 deletions(-) create mode 100644 JUST.Net.Test/PathNotExistsTest.cs create mode 100644 JUST.net/Exception/PathNotFoundException.cs diff --git a/JUST.Net.Test/DynamicExpressoArrayTest.cs b/JUST.Net.Test/DynamicExpressoArrayTest.cs index 7b994e9..9764b16 100644 --- a/JUST.Net.Test/DynamicExpressoArrayTest.cs +++ b/JUST.Net.Test/DynamicExpressoArrayTest.cs @@ -13,7 +13,7 @@ public void Array_ValueOf_Object_Test() { var input = @"{ ""array"": [ { ""name"": ""hans"" }, { ""name"": ""simplic"" } ] }"; - var transformer = @"{ ""ar"": { ""#loop($.array)"": { ""n"": ""~(valueOfIterStr(\""$.name\""))"" } } }"; + var transformer = @"{ ""ar"": { ""#loop($.array)"": { ""n"": ""~(valueOfIterStr(\""$.name\""))"", ""index"": ""~(currentIndex)"" } } }"; var jsonTransformer = new JsonTransformer(); var result = jsonTransformer.Transform(transformer, input); @@ -21,6 +21,9 @@ public void Array_ValueOf_Object_Test() var obj = JObject.Parse(result); Assert.Equal("hans", obj.SelectToken("$.ar[0].n").Value()); Assert.Equal("simplic", obj.SelectToken("$.ar[1].n").Value()); + + Assert.Equal(0, obj.SelectToken("$.ar[0].index").Value()); + Assert.Equal(1, obj.SelectToken("$.ar[1].index").Value()); Assert.True(true); } } diff --git a/JUST.Net.Test/PathNotExistsTest.cs b/JUST.Net.Test/PathNotExistsTest.cs new file mode 100644 index 0000000..acc81bb --- /dev/null +++ b/JUST.Net.Test/PathNotExistsTest.cs @@ -0,0 +1,84 @@ +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace JUST.Net.Test +{ + public class PathNotExistsTest + { + [Fact] + public void PathNotExists_Test_Str() + { + var input = @"{ }"; + + var transformer = @"{ ""val"": ""~(valueOfStr(\""$.test.test.test\""))"" }"; + + var jsonTransformer = new JsonTransformer(); + var result = jsonTransformer.Transform(transformer, input); + + var obj = JObject.Parse(result); + Assert.Equal("", obj.SelectToken("$.val").Value()); + Assert.True(true); + } + + [Fact] + public void PathNotExists_Test_Int() + { + var input = @"{ }"; + + var transformer = @"{ ""val"": ""~(valueOfInt(\""$.test.test.test\""))"" }"; + + var jsonTransformer = new JsonTransformer(); + var result = jsonTransformer.Transform(transformer, input); + + var obj = JObject.Parse(result); + Assert.Equal(0, obj.SelectToken("$.val").Value()); + Assert.True(true); + } + + [Fact] + public void PathNotExists_Test_Double() + { + var input = @"{ }"; + + var transformer = @"{ ""val"": ""~(valueOfDouble(\""$.test.test.test\""))"" }"; + + var jsonTransformer = new JsonTransformer(); + var result = jsonTransformer.Transform(transformer, input); + + var obj = JObject.Parse(result); + Assert.Equal(0.0, obj.SelectToken("$.val").Value()); + Assert.True(true); + } + + [Fact] + public void PathNotExists_Test_Str_Exception() + { + var input = @"{ }"; + + var transformer = @"{ ""val"": ""~(valueOfStr(\""$.test.test.test\""))"" }"; + + var jsonTransformer = new JsonTransformer + { + StrictPathHandling = true + }; + + var exceptionCaused = false; + + try + { + jsonTransformer.Transform(transformer, input); + } + catch (PathNotFoundException ex) + { + exceptionCaused = true; + Assert.Contains("$.test.test.test", ex.Message); + } + + Assert.True(exceptionCaused); + } + } +} diff --git a/JUST.net/Exception/ExpressionException.cs b/JUST.net/Exception/ExpressionException.cs index 900afa2..f08982e 100644 --- a/JUST.net/Exception/ExpressionException.cs +++ b/JUST.net/Exception/ExpressionException.cs @@ -3,7 +3,7 @@ using System.Runtime.Serialization; using System.Text; -namespace JUST.net +namespace JUST { public class ExpressionException : Exception { diff --git a/JUST.net/Exception/PathNotFoundException.cs b/JUST.net/Exception/PathNotFoundException.cs new file mode 100644 index 0000000..0c59627 --- /dev/null +++ b/JUST.net/Exception/PathNotFoundException.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; +using System.Text; + +namespace JUST +{ + public class PathNotFoundException : Exception + { + public PathNotFoundException() + { + } + + public PathNotFoundException(string message) : base(message) + { + } + + public PathNotFoundException(string message, Exception innerException) : base(message, innerException) + { + } + + protected PathNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } +} diff --git a/JUST.net/ExpressionInterpreter.cs b/JUST.net/ExpressionInterpreter.cs index 82b9b47..c1bad8e 100644 --- a/JUST.net/ExpressionInterpreter.cs +++ b/JUST.net/ExpressionInterpreter.cs @@ -2,6 +2,7 @@ using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; +using System.Linq; using System.Text; namespace JUST.net @@ -11,6 +12,8 @@ namespace JUST.net /// internal class ExpressionInterpreter : Interpreter { + private bool strictPathHandling; + /// /// Initialize interpreter /// @@ -25,18 +28,20 @@ public ExpressionInterpreter() /// /// Initialize core methods /// - public void Setup(JToken inputObject) + public void Setup(JToken inputObject, bool strictPathHandling) { - Func valueOfStr = (path) => Transformer.valueof(path, inputObject).ToString(); - Func valueOf = (path) => Transformer.valueof(path, inputObject); + this.strictPathHandling = strictPathHandling; + + Func valueOfStr = (path) => Transformer.ValueOf(path, inputObject, strictPathHandling, "").ToString(); + Func valueOf = (path) => Transformer.ValueOf(path, inputObject, strictPathHandling, new object()); Func valueOfInt = (path) => { - int.TryParse(Transformer.valueof(path, inputObject)?.ToString(), out int r); + int.TryParse(Transformer.ValueOf(path, inputObject, strictPathHandling, 0)?.ToString(), out int r); return r; }; Func valueOfDouble = (path) => { - double.TryParse(Transformer.valueof(path, inputObject)?.ToString(), out double r); + double.TryParse(Transformer.ValueOf(path, inputObject, strictPathHandling, 0)?.ToString(), out double r); return r; }; Func nullToString = (value) => value ?? ""; @@ -51,18 +56,18 @@ public void Setup(JToken inputObject) /// /// Initialize core methods /// - public void SetContext(JToken arrayElement) + public void SetContext(JToken arrayElement, JArray array, string expression) { - Func valueOfStr = (path) => Transformer.valueof(path, arrayElement).ToString(); - Func valueOf = (path) => Transformer.valueof(path, arrayElement); + Func valueOfStr = (path) => Transformer.ValueOf(path, arrayElement, strictPathHandling, "").ToString(); + Func valueOf = (path) => Transformer.ValueOf(path, arrayElement, strictPathHandling, new object()); Func valueOfInt = (path) => { - int.TryParse(Transformer.valueof(path, arrayElement)?.ToString(), out int r); + int.TryParse(Transformer.ValueOf(path, arrayElement, strictPathHandling, 0)?.ToString(), out int r); return r; }; Func valueOfDouble = (path) => { - double.TryParse(Transformer.valueof(path, arrayElement)?.ToString(), out double r); + double.TryParse(Transformer.ValueOf(path, arrayElement, strictPathHandling, 0)?.ToString(), out double r); return r; }; @@ -70,6 +75,30 @@ public void SetContext(JToken arrayElement) SetFunction("valueOfIterStr", valueOfStr); SetFunction("valueOfIterInt", valueOfInt); SetFunction("valueOfIterDouble", valueOfDouble); + + var identifiers = DetectIdentifiers(expression); + if (identifiers != null) + { + foreach (var identifier in identifiers.UnknownIdentifiers) + { + switch (identifier) + { + case "currentIndex": + SetVariable("currentIndex", array.IndexOf(arrayElement)); + break; + } + } + + foreach (var identifier in identifiers.Identifiers.Select(x => x.Name)) + { + switch (identifier) + { + case "currentIndex": + SetVariable("currentIndex", array.IndexOf(arrayElement)); + break; + } + } + } } } } diff --git a/JUST.net/JUST.net.csproj b/JUST.net/JUST.net.csproj index d2a1e7e..44846bc 100644 --- a/JUST.net/JUST.net.csproj +++ b/JUST.net/JUST.net.csproj @@ -14,9 +14,9 @@ This will repace the JUST and JUST.NETCore packages. Fixed the following issues:- https://github.com/WorkMaze/JUST.net/issues/26 https://github.com/WorkMaze/JUST.net/issues/25 - 5.8.320.825 - 5.8.320.825 - 5.8.320 + 5.8.420.825 + 5.8.420.825 + 5.8.420 diff --git a/JUST.net/JsonTransformer.cs b/JUST.net/JsonTransformer.cs index 1285597..2552fe7 100644 --- a/JUST.net/JsonTransformer.cs +++ b/JUST.net/JsonTransformer.cs @@ -100,7 +100,7 @@ public JObject Transform(JObject transformer, string input) reader.DateParseHandling = DateParseHandling.None; inputObject = JObject.Load(reader); - expressionInterpreter.Setup(inputObject); + expressionInterpreter.Setup(inputObject, StrictPathHandling); RecursiveEvaluate(transformer, input, null, null); return transformer; @@ -201,16 +201,20 @@ private void RecursiveEvaluate(JToken parentToken, string inputJson, JArray pare if (ExpressionParserUtilities.IsExpression(property.Value.ToString().Trim(), out string expression)) { - expressionInterpreter.SetContext(currentArrayToken); + expressionInterpreter.SetContext(currentArrayToken, parentArray, expression); try { var result = expressionInterpreter.Eval(expression); property.Value = new JValue(result); } + catch (PathNotFoundException ex) + { + throw; + } catch (Exception ex) { - throw new Exception($"Could not execute expression: {expression}", ex); + throw new Exception($"Could not execute expression: {expression}. Property: {property}.", ex); } } @@ -841,5 +845,11 @@ private int GetIndexOfFunctionEnd(string totalString) return index; } + + /// + /// Gets or sets whether to use strict path handling. If set to true, an exception will be caused + /// if a path is not existing. + /// + public bool StrictPathHandling { get; set; } = false; } } diff --git a/JUST.net/Transformer.cs b/JUST.net/Transformer.cs index ccb6fc9..ce93d12 100644 --- a/JUST.net/Transformer.cs +++ b/JUST.net/Transformer.cs @@ -8,10 +8,19 @@ namespace JUST { internal class Transformer { - public static object valueof(string jsonPath, JToken input) + public static object ValueOf(string jsonPath, JToken input, bool strictPathHandling, object defaultValue) { JToken selectedToken = input.SelectToken(jsonPath); - return GetValue(selectedToken); + + if (strictPathHandling) + { + if (selectedToken == null) + { + throw new PathNotFoundException($"Could not find object at path: {jsonPath},"); + } + } + + return GetValue(selectedToken, defaultValue); } public static string getcurrentscopeasstring(string inputJson) @@ -571,45 +580,34 @@ public static string arraylength(string array, string inputJson) #endregion - #region arraylooping - public static object currentvalue(JArray array, JToken currentElement) - { - - return GetValue(currentElement); - } - - public static string currentindex(JArray array, JToken currentElement) - { - return array.IndexOf(currentElement).ToString(); - } - - - public static object lastvalue(JArray array, JToken currentElement) - { - - return GetValue(array.Last); - } - - public static string lastindex(JArray array, JToken currentElement) - { - return (array.Count - 1).ToString(); - } - - public static object currentvalueatpath(JArray array, JToken currentElement, string jsonPath) - { - JToken selectedToken = currentElement.SelectToken(jsonPath); - - return GetValue(selectedToken); - } - - public static object lastvalueatpath(JArray array, JToken currentElement, string jsonPath) - { - - JToken selectedToken = array.Last.SelectToken(jsonPath); - - return GetValue(selectedToken); - } - #endregion + // #region arraylooping + // public static object currentvalue(JArray array, JToken currentElement) + // { + // + // return GetValue(currentElement); + // } + // + // + // + // public static object lastvalue(JArray array, JToken currentElement) + // { + // + // return GetValue(array.Last); + // } + // + // public static string lastindex(JArray array, JToken currentElement) + // { + // return (array.Count - 1).ToString(); + // } + // + // public static object lastvalueatpath(JArray array, JToken currentElement, string jsonPath) + // { + // + // JToken selectedToken = array.Last.SelectToken(jsonPath); + // + // return GetValue(selectedToken); + // } + // #endregion #region Constants @@ -625,9 +623,9 @@ public static string constant_hash(string inputJson) #endregion - public static object GetValue(JToken selectedToken) + public static object GetValue(JToken selectedToken, object defaultValue) { - object output = null; + object output = defaultValue; if (selectedToken != null) { if (selectedToken.Type == JTokenType.Date) diff --git a/JUST.net/Utilities.cs b/JUST.net/Utilities.cs index 4c757ef..d9c8d83 100644 --- a/JUST.net/Utilities.cs +++ b/JUST.net/Utilities.cs @@ -33,7 +33,7 @@ public static JArray GroupArray(JArray array, string groupingPropertyName, strin if (groupToken != null) { - object valueOfToken = Transformer.GetValue(groupToken); + object valueOfToken = Transformer.GetValue(groupToken, null); if (groupedPair.ContainsKey(valueOfToken.ToString())) { @@ -100,7 +100,7 @@ public static JArray GroupArrayMultipleProperties(JArray array, string[] groupin foreach (JToken groupToken in groupTokens) { - object valueOfToken = Transformer.GetValue(groupToken); + object valueOfToken = Transformer.GetValue(groupToken, null); if (key == string.Empty) key += valueOfToken; else From 0b1aa99eb23d9598f8761156a251fd3c10e256f2 Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Sun, 6 Sep 2020 01:50:01 +0200 Subject: [PATCH 34/43] Remove string op --- JUST.Net.Test/DynamicExpressoArrayTest.cs | 5 +- JUST.net/ExpressionInterpreter.cs | 13 +--- JUST.net/Transformer.cs | 91 +---------------------- 3 files changed, 9 insertions(+), 100 deletions(-) diff --git a/JUST.Net.Test/DynamicExpressoArrayTest.cs b/JUST.Net.Test/DynamicExpressoArrayTest.cs index 9764b16..5acb470 100644 --- a/JUST.Net.Test/DynamicExpressoArrayTest.cs +++ b/JUST.Net.Test/DynamicExpressoArrayTest.cs @@ -13,7 +13,7 @@ public void Array_ValueOf_Object_Test() { var input = @"{ ""array"": [ { ""name"": ""hans"" }, { ""name"": ""simplic"" } ] }"; - var transformer = @"{ ""ar"": { ""#loop($.array)"": { ""n"": ""~(valueOfIterStr(\""$.name\""))"", ""index"": ""~(currentIndex)"" } } }"; + var transformer = @"{ ""ar"": { ""#loop($.array)"": { ""n"": ""~(valueOfIterStr(\""$.name\""))"", ""index"": ""~(currentIndex)"", ""last"": ""~(lastIndex)"" } } }"; var jsonTransformer = new JsonTransformer(); var result = jsonTransformer.Transform(transformer, input); @@ -24,6 +24,9 @@ public void Array_ValueOf_Object_Test() Assert.Equal(0, obj.SelectToken("$.ar[0].index").Value()); Assert.Equal(1, obj.SelectToken("$.ar[1].index").Value()); + + Assert.Equal(1, obj.SelectToken("$.ar[0].last").Value()); + Assert.Equal(1, obj.SelectToken("$.ar[1].last").Value()); Assert.True(true); } } diff --git a/JUST.net/ExpressionInterpreter.cs b/JUST.net/ExpressionInterpreter.cs index c1bad8e..158bc3d 100644 --- a/JUST.net/ExpressionInterpreter.cs +++ b/JUST.net/ExpressionInterpreter.cs @@ -79,22 +79,17 @@ public void SetContext(JToken arrayElement, JArray array, string expression) var identifiers = DetectIdentifiers(expression); if (identifiers != null) { - foreach (var identifier in identifiers.UnknownIdentifiers) + + foreach (var identifier in identifiers.UnknownIdentifiers.Concat(identifiers.Identifiers.Select(x => x.Name))) { switch (identifier) { case "currentIndex": SetVariable("currentIndex", array.IndexOf(arrayElement)); break; - } - } - foreach (var identifier in identifiers.Identifiers.Select(x => x.Name)) - { - switch (identifier) - { - case "currentIndex": - SetVariable("currentIndex", array.IndexOf(arrayElement)); + case "lastIndex": + SetVariable("lastIndex", array.IndexOf(array.Last)); break; } } diff --git a/JUST.net/Transformer.cs b/JUST.net/Transformer.cs index ce93d12..b1cf6e2 100644 --- a/JUST.net/Transformer.cs +++ b/JUST.net/Transformer.cs @@ -91,62 +91,6 @@ public static object ifcondition(object condition, object value, object trueResu #region string functions - /// - /// Compare to values - /// - /// Basic value - /// Value to compare with - /// Json object - /// True if the objects are equal - public static bool equals(string @this, string other, string inputJson) - { - return @this == other; - } - - public static string substring(string stringRef, string startIndex, string length, string inputJson) - { - try - { - return stringRef.Substring(Convert.ToInt32(startIndex), Convert.ToInt32(length)); - } - catch - { - return null; - } - } - - public static string trimstart(string value, string trimChar, string inputJson) - { - if (string.IsNullOrEmpty(trimChar)) - return value; - - return value?.TrimStart(trimChar[0]); - } - - public static string trimend(string value, string trimChar, string inputJson) - { - if (string.IsNullOrEmpty(trimChar)) - return value; - - return value?.TrimEnd(trimChar[0]); - } - - public static string trim(string value, string inputJson) - { - return value?.Trim(); - } - - public static string replacestring(string value, string searchString, string replaceString, string inputJson) - { - if (searchString == null) - return value; - - if (replaceString == null) - return value; - - return value?.Replace(searchString, replaceString); - } - public static string firstindexof(string stringRef, string searchString, string inputJson) { return stringRef.IndexOf(searchString, 0).ToString(); @@ -580,26 +524,7 @@ public static string arraylength(string array, string inputJson) #endregion - // #region arraylooping - // public static object currentvalue(JArray array, JToken currentElement) - // { - // - // return GetValue(currentElement); - // } - // - // - // - // public static object lastvalue(JArray array, JToken currentElement) - // { - // - // return GetValue(array.Last); - // } - // - // public static string lastindex(JArray array, JToken currentElement) - // { - // return (array.Count - 1).ToString(); - // } - // + // #region arraylooping // public static object lastvalueatpath(JArray array, JToken currentElement, string jsonPath) // { // @@ -609,20 +534,6 @@ public static string arraylength(string array, string inputJson) // } // #endregion - #region Constants - - public static string constant_comma(string inputJson) - { - return ","; - } - - public static string constant_hash(string inputJson) - { - return "#"; - } - - #endregion - public static object GetValue(JToken selectedToken, object defaultValue) { object output = defaultValue; From bf9cf15510abc4f68d3bda1cd7aaae7e0a1abd93 Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Mon, 7 Sep 2020 10:15:07 +0200 Subject: [PATCH 35/43] Remove not required code --- Examples/Array/base.xml | 38 ----- Examples/Array/input_array.json | 38 ----- Examples/Array/transform_array.json | 24 --- Examples/DataTransformer.csv | 1 - Examples/DataTransformer.xml | 71 --------- Examples/Input.json | 146 ------------------ Examples/InputDynamic.json | 6 - Examples/InputSpecial.json | 19 --- Examples/InputToSplit.json | 42 ----- Examples/Input_Unordered.json | 40 ----- Examples/Input_Unordered_2.json | 41 ----- Examples/SchemaX.json | 16 -- Examples/SchemaY.json | 5 - Examples/TransformDynamic.json | 18 --- Examples/Transform_Unordered.json | 3 - Examples/Transform_Unordered_2.json | 5 - Examples/Transformer.json | 86 ----------- Examples/Transformer_Existance.json | 8 - Examples/Transformer_Math.json | 15 -- Examples/Transformer_aggregate.json | 7 - Examples/Transformer_array.json | 8 - Examples/Transformer_arrayaggregate.json | 7 - Examples/Transformer_copy.json | 3 - Examples/Transformer_customfunction.json | 3 - .../Transformer_customfunctionspecial.json | 3 - Examples/Transformer_delete.json | 3 - Examples/Transformer_externalmethods.json | 15 -- Examples/Transformer_ifcondition.json | 4 - Examples/Transformer_looping.json | 22 --- Examples/Transformer_looptests.json | 27 ---- Examples/Transformer_nestedfunctions.json | 13 -- Examples/Transformer_nestedloop.json | 12 -- Examples/Transformer_replace.json | 3 - Examples/Transformer_string.json | 8 - Examples/Transformer_valueof.json | 7 - Examples/Transformer_valueofarray.json | 11 -- Examples/Transformer_xfunctions.json | 4 - Examples/ValidationInput.json | 5 - ExternalMethods/ExternalClass.cs | 33 ---- ExternalMethods/ExternalMethods.csproj | 11 -- ExternalMethods/Season.cs | 12 -- JUST.NET.sln | 8 +- JUST.net/ExpressionInterpreter.cs | 8 + JUST.net/Transformer.cs | 90 +---------- 44 files changed, 10 insertions(+), 939 deletions(-) delete mode 100644 Examples/Array/base.xml delete mode 100644 Examples/Array/input_array.json delete mode 100644 Examples/Array/transform_array.json delete mode 100644 Examples/DataTransformer.csv delete mode 100644 Examples/DataTransformer.xml delete mode 100644 Examples/Input.json delete mode 100644 Examples/InputDynamic.json delete mode 100644 Examples/InputSpecial.json delete mode 100644 Examples/InputToSplit.json delete mode 100644 Examples/Input_Unordered.json delete mode 100644 Examples/Input_Unordered_2.json delete mode 100644 Examples/SchemaX.json delete mode 100644 Examples/SchemaY.json delete mode 100644 Examples/TransformDynamic.json delete mode 100644 Examples/Transform_Unordered.json delete mode 100644 Examples/Transform_Unordered_2.json delete mode 100644 Examples/Transformer.json delete mode 100644 Examples/Transformer_Existance.json delete mode 100644 Examples/Transformer_Math.json delete mode 100644 Examples/Transformer_aggregate.json delete mode 100644 Examples/Transformer_array.json delete mode 100644 Examples/Transformer_arrayaggregate.json delete mode 100644 Examples/Transformer_copy.json delete mode 100644 Examples/Transformer_customfunction.json delete mode 100644 Examples/Transformer_customfunctionspecial.json delete mode 100644 Examples/Transformer_delete.json delete mode 100644 Examples/Transformer_externalmethods.json delete mode 100644 Examples/Transformer_ifcondition.json delete mode 100644 Examples/Transformer_looping.json delete mode 100644 Examples/Transformer_looptests.json delete mode 100644 Examples/Transformer_nestedfunctions.json delete mode 100644 Examples/Transformer_nestedloop.json delete mode 100644 Examples/Transformer_replace.json delete mode 100644 Examples/Transformer_string.json delete mode 100644 Examples/Transformer_valueof.json delete mode 100644 Examples/Transformer_valueofarray.json delete mode 100644 Examples/Transformer_xfunctions.json delete mode 100644 Examples/ValidationInput.json delete mode 100644 ExternalMethods/ExternalClass.cs delete mode 100644 ExternalMethods/ExternalMethods.csproj delete mode 100644 ExternalMethods/Season.cs diff --git a/Examples/Array/base.xml b/Examples/Array/base.xml deleted file mode 100644 index b6bcd53..0000000 --- a/Examples/Array/base.xml +++ /dev/null @@ -1,38 +0,0 @@ - - -
- 1024 - Sample street - 1 -
-
- 3303 - L-Street - 23 -
- - 1024 - Max - Sample - - 25 - - - - 1024 - Mina - Sample - - 26 - - - - 3303 - Laura - Rickfield - - 54 - - -
-
\ No newline at end of file diff --git a/Examples/Array/input_array.json b/Examples/Array/input_array.json deleted file mode 100644 index 385bae9..0000000 --- a/Examples/Array/input_array.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "root": { - "items": { - "address": [ - { - "id": "001024", - "street": "Sample street", - "houseNr": "1" - }, - { - "id": "003303", - "street": "L-Street", - "houseNr": "23" - } - ], - "inhabitant": [ - { - "addressId": "001024", - "firstName": "Max", - "lastName": "Sample", - "data": { "age": "25" } - }, - { - "addressId": "001024", - "firstName": "Mina", - "lastName": "Sample", - "data": { "age": "26" } - }, - { - "addressId": "003303", - "firstName": "Laura", - "lastName": "Rickfield", - "data": { "age": "54" } - } - ] - } - } -} \ No newline at end of file diff --git a/Examples/Array/transform_array.json b/Examples/Array/transform_array.json deleted file mode 100644 index 509e713..0000000 --- a/Examples/Array/transform_array.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "addresses": { - "#loop($.root.items.address)": { - "id": "#currentvalueatpath($.id)", - "maxAge": "#maxatpath(#getarray(#getroot(), #xconcat($.root.items.inhabitant[?(@.addressId==',#currentvalueatpath($.id),')])), $.data.age)", - "ageSum": "#sumatpath(#getarray(#getroot(), #xconcat($.root.items.inhabitant[?(@.addressId==',#currentvalueatpath($.id),')])), $.data.age)", - "listAtPath": "#listallatpath(#getarray(#getroot(), #xconcat($.root.items.inhabitant[?(@.addressId==',#currentvalueatpath($.id),')])), $.firstName,;)", - "inhabitantsCount": "#count(#getarray(#getroot(), #xconcat($.root.items.inhabitant[?(@.addressId==',#currentvalueatpath($.id),')])))", - "inhabitants": { - "#loop($.root.items.inhabitant[?(@.addressId=='#currentvalueatpath($.id)')])": { - "firstName": "#currentvalueatpath($.firstName)", - "lastName": "#currentvalueatpath($.lastName)", - "parentId": "#valueof(#xconcat($.root.items.address[?(@.id==',#currentvalueatpath($.addressId),')].id))", - "parentStret": "#valueof(#xconcat($.root.items.address[?(@.id==',#currentvalueatpath($.addressId),')].street))" - } - }, - "counter_array": { - "#loop(#createarray(3,count_item,parentId,#currentvalueatpath($.id)))": { - "id": "#currentvalueatpath($.parentId)" - } - } - } - } -} \ No newline at end of file diff --git a/Examples/DataTransformer.csv b/Examples/DataTransformer.csv deleted file mode 100644 index ac6f641..0000000 --- a/Examples/DataTransformer.csv +++ /dev/null @@ -1 +0,0 @@ -"#loop($.numbers)": {#currentvalue(),#currentindex(),#ifcondition(#currentindex(),#lastindex(),yes,no),#lastvalue(),#valueof($.LogId)} \ No newline at end of file diff --git a/Examples/DataTransformer.xml b/Examples/DataTransformer.xml deleted file mode 100644 index 99998a7..0000000 --- a/Examples/DataTransformer.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - - #ifcondition(#valueof($.menu.id.file),csv,#valueof($.menu.value.Window),fail) - #ifcondition(#valueof($.menu.id.file),xml,#valueof($.menu.value.Window),fail) - - #lastindexof(#valueof($.stringref),and) - #firstindexof(#valueof($.stringref),and) - #substring(#valueof($.stringref),8,10) - #concat(#valueof($.menu.id.file),#valueof($.menu.value.Window)) - - - #equals(#valueof($.menu.id.file),#valueof($.menu.value.Window)) - #equals(#valueof($.menu.id.file),csv) - #equals(Value1,Value2) - - - #add(#valueof($.numbers[0]),3) - #subtract(#valueof($.numbers[4]),#valueof($.numbers[0])) - #multiply(2,#valueof($.numbers[2])) - #divide(9,3) - - #concatall(#valueof($.d)) - #sum(#valueof($.numbers)) - #average(#valueof($.numbers)) - #min(#valueof($.numbers)) - #max(#valueof($.numbers)) - #concatallatpath(#valueof($.x),$.v.a) - #sumatpath(#valueof($.x),$.v.c) - #averageatpath(#valueof($.x),$.v.c) - #minatpath(#valueof($.x),$.v.b) - #maxatpath(#valueof($.x),$.v.b) - - #concat(#concat(#concat(#valueof($.Name), ),#concat(#valueof($.MiddleName), )),#valueof($.Surname)) - - #substring(#valueof($.ContactInformation),#add(#firstindexof(#valueof($.ContactInformation),:),1),#subtract(#subtract(#lastindexof(#valueof($.ContactInformation),:),#firstindexof(#valueof($.ContactInformation),:)),1)) - #substring(#valueof($.ContactInformation),#add(#lastindexof(#valueof($.ContactInformation),:),1),#subtract(#lastindexof(#valueof($.ContactInformation),),#lastindexof(#valueof($.ContactInformation),:))) - #substring(#valueof($.ContactInformation),0,#firstindexof(#valueof($.ContactInformation),:)) - - - #substring(#valueof($.PersonalInformation),0,#firstindexof(#valueof($.PersonalInformation),:)) - #substring(#valueof($.PersonalInformation),#add(#lastindexof(#valueof($.PersonalInformation),:),1),#subtract(#lastindexof(#valueof($.PersonalInformation),),#lastindexof(#valueof($.PersonalInformation),:))) - #valueof($.LogId) - #substring(#valueof($.PersonalInformation),#add(#firstindexof(#valueof($.PersonalInformation),:),1),#subtract(#subtract(#lastindexof(#valueof($.PersonalInformation),:),#firstindexof(#valueof($.PersonalInformation),:)),1)) - - #customfunction(JUST.NET.Test,JUST.NET.Test.Season.findseason,#valueof($.tree.branch.leaf),#valueof($.tree.branch.flower)) - - "#loop($.numbers,)": { - - #currentvalue() - #currentindex() - #ifcondition(#currentindex(),#lastindex(),yes,no) - #lastvalue() - #valueof($.LogId) - } - - - - 1 - #valueof($.menu.id.file) - - - 2 - #valueof($.menu.id.file) - - - 3 - #valueof($.menu.id.file) - - - \ No newline at end of file diff --git a/Examples/Input.json b/Examples/Input.json deleted file mode 100644 index 3b5e9fc..0000000 --- a/Examples/Input.json +++ /dev/null @@ -1,146 +0,0 @@ -{ - "menu": { - "id": { - "file": "csv" - - }, - "value": { - "Window": "popup" - }, - "popup": { - "menuitem": [ - { - "value": "New", - "onclick": { - "action": "CreateNewDoc()" - } - }, - { - "value": "Open", - "onclick": "OpenDoc()" - }, - { - "value": "Close", - "onclick": "CloseDoc()" - } - ] - } - }, - "x": [ - { - "v": { - "a": "a1,a2,a3", - "b": "1", - "c": "10" - } - }, - { - "v": { - "a": "b1,b2", - "b": "2", - "c": "20" - } - - }, - { - "v": { - "a": "c1,c2,c3", - "b": "3", - "c": "30" - } - } - ], - "stringref": "thisisandveryunuasualandlongstring", - "d": [ "one", "two", "three" ], - "numbers": [ "1", "2", "3", "4", "5" ], - "tree": { - "branch": { - "leaf": "green", - "flower": "red", - "bird": "crow" - } - }, - "season": { - "characteristics": { - "hot": true, - "averageDaysOfRain": 10, - "randomDay": "2018-08-01T00:00:00.000Z" - } - }, - "Name": "Kari", - "Surname": "Nordmann", - "MiddleName": "Inger", - "ContactInformation": "Karl johans gate:Oslo:88880000", - "PersonalInformation": "45:Married:Norwegian", - "AgeOfMother": "67", - "AgeOfFather": "70", - "BuyDate": "2017-04-10T11:36:39+03:00", - "ExpireDate": "", - "LogId": 5000510625, - "NestedLoop": { - "Organization": { - "Employee": [ - { - "Name": "E2", - "Details": [ - { - "Country": "Iceland", - "Age": "30", - "Name": "Sven", - "Language": "Icelandic" - } - ] - }, - { - "Name": "E1", - "Details": [ - { - "Country": "Denmark", - "Age": "30", - "Name": "Svein", - "Language": "Danish" - } - ] - } - ] - } - }, - "people": [ - { - "name": "Jim", - "phoneNumbers": [ - { - "type": "iPhone", - "number": "0123-4567-8888", - "countryPrefix": "34" - }, - { - "type": "work", - "number": "012567-8910" - } - ] - }, - { - "name": "John", - "phoneNumbers": [ - { - "type": "iPhone", - "number": "0123-4562347-8888", - "countryPrefix": "43" - }, - { - "type": "home", - "number": "0134523-4567-8910" - } - ] - }, - { - "name": "John" - } - ], - "PhoneTypeToSearch": "iPhone", - "DataForArrayTransformer": { - "Field1": "Value1", - "Field2": "Value2" - } -} \ No newline at end of file diff --git a/Examples/InputDynamic.json b/Examples/InputDynamic.json deleted file mode 100644 index 7069fc7..0000000 --- a/Examples/InputDynamic.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "Tree": { - "Branch": "leaf", - "Flower": "Rose" - } -} \ No newline at end of file diff --git a/Examples/InputSpecial.json b/Examples/InputSpecial.json deleted file mode 100644 index edb618a..0000000 --- a/Examples/InputSpecial.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "cardExpire": "09/2019", - "orderPlaceDateLong": "Tue 10 October 2017", - "shippingAddress2": "#F370 F370", - "shippingAddressZip": "\\33486-2159", - "shippingAddress1": "1231 NW 13th St Apt 370F", - "orderTotal": "22.48", - "cardType": "Visa", - "orderShipping": "0.00", - "shippingLastName": "Doe", - "shippingFirstName": "Jane", - "orderSubtotal": "22.48", - "shippingAddressTown": "Boca Raton", - "firstName": "Jane", - "lastName": "Doe", - "orderPlaceDateShort": "10/10/2017", - "shippingAdressState": null, - "orderTotalSavings": "2.50" -} \ No newline at end of file diff --git a/Examples/InputToSplit.json b/Examples/InputToSplit.json deleted file mode 100644 index 9b1e275..0000000 --- a/Examples/InputToSplit.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "cars": { - "Ford": [ - { - "model": "Taurus", - "doors": 4 - }, - { - "model": "Escort", - "doors": 4 - }, - { - "model": "Fiesta", - "doors": 3 - }, - { - "model": "Bronco", - "doors": 5 - } - ], - "firstName": "John", - "lastName": "Smith", - "age": 25, - "address": { - "streetAddress": "21 2nd Street", - "city": "New York", - "state": "NY", - "postalCode": "10021" - }, - "phoneNumber": [ - { - "type": "home", - "number": "212 555-1234" - }, - { - "type": "fax", - "number": "646 555-4567" - } - ] - - } -} \ No newline at end of file diff --git a/Examples/Input_Unordered.json b/Examples/Input_Unordered.json deleted file mode 100644 index f9eedff..0000000 --- a/Examples/Input_Unordered.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "Forest": [ - { - "type": "Mammal", - "qty": 1, - "name": "Hippo" - }, - - { - "type": "Bird", - "qty": 2, - "name": "Sparrow" - }, - - { - "type": "Amphibian", - "qty": 300, - "name": "Lizard" - }, - - { - "type": "Bird", - "qty": 3, - "name": "Parrot" - }, - - { - "type": "Mammal", - "qty": 1, - "name": "Elephant" - }, - { - "type": "Mammal", - "qty": 10, - "name": "Dog" - } - - - ] -} \ No newline at end of file diff --git a/Examples/Input_Unordered_2.json b/Examples/Input_Unordered_2.json deleted file mode 100644 index bcbd87d..0000000 --- a/Examples/Input_Unordered_2.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "Vehicle": [ - { - "type": "air", - "company": "Boeing", - "name": "airplane" - }, - - { - "type": "air", - "company": "Concorde", - "name": "airplane" - }, - - { - "type": "air", - "company": "Boeing", - "name": "Chopper" - }, - - { - "type": "land", - "company": "GM", - "name": "car" - }, - - { - "type": "sea", - "company": "Viking", - "name": "ship" - }, - { - "type": "land", - "company": "GM", - "name": "truck" - } - - - ] - -} \ No newline at end of file diff --git a/Examples/SchemaX.json b/Examples/SchemaX.json deleted file mode 100644 index d50446d..0000000 --- a/Examples/SchemaX.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "properties": { - "tree": { - "type": "object", - "properties": { - "branch": { - "type": "object", - "properties": { - "leaf": { "type": "string" } - } - } - } - }, - "child": { "type": "string" } - } -} diff --git a/Examples/SchemaY.json b/Examples/SchemaY.json deleted file mode 100644 index f847a42..0000000 --- a/Examples/SchemaY.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "properties": { - "animal": { "type": "string" } - } -} diff --git a/Examples/TransformDynamic.json b/Examples/TransformDynamic.json deleted file mode 100644 index 28ab874..0000000 --- a/Examples/TransformDynamic.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "Result": { - "Header": "JsonTransform", - "#ifgroup(#exists($.Tree.Branch))": { - "State": { - "Value1": "#valueof($.Tree.Branch)", - "Value2": "#valueof($.Tree.Flower)" - } - }, - "#eval(#valueof($.Tree.Flower))": "x", - "#ifgroup(#exists($.Tree.Flower))": { - "Comment": { - "Statement": "Flower Exists" - } - } - } - -} \ No newline at end of file diff --git a/Examples/Transform_Unordered.json b/Examples/Transform_Unordered.json deleted file mode 100644 index 9d5fbf5..0000000 --- a/Examples/Transform_Unordered.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "Result": "#grouparrayby($.Forest,type,all)" -} \ No newline at end of file diff --git a/Examples/Transform_Unordered_2.json b/Examples/Transform_Unordered_2.json deleted file mode 100644 index 0cbf0b4..0000000 --- a/Examples/Transform_Unordered_2.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "Result": "#grouparrayby($.Vehicle,type:company,all)" - - -} \ No newline at end of file diff --git a/Examples/Transformer.json b/Examples/Transformer.json deleted file mode 100644 index 77576d5..0000000 --- a/Examples/Transformer.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "#": [ "#copy($)", "#copy($.menu.id)", "#copy($.menu.value)", "#delete($.menu.popup)", "#replace($.menu.id,#valueof($.menu.value))" ], - "root": { - "menu1": "#valueof($.menu.popup.menuitem[?(@.value=='New')].onclick)", - "menu2": "#valueof($.menu.popup.menuitem[?(@.value=='Open')].onclick)", - "array": { - "fullarray": "#valueof($.x)", - "arrayelement": "#valueof($.x[0])", - "specificelement": "#valueof($.x[1].v.a)" - }, - "boolresult": { - "equals": "#equals(#valueof($.menu.id.file),#valueof($.menu.value.Window))", - "equals_val": "#equals(#valueof($.menu.id.file),csv)", - "equals_value": "#equals(Value1,Value2)" - }, - "ifconditiontesttrue": "#ifcondition(#valueof($.menu.id.file),csv,#valueof($.menu.value.Window),fail)", - "ifconditiontestfalse": "#ifcondition(#valueof($.menu.id.file),xml,#valueof($.menu.value.Window),fail)", - "stringresult": { - "lastindexofand": "#lastindexof(#valueof($.stringref),and)", - "firstindexofand": "#firstindexof(#valueof($.stringref),and)", - "subsrting": "#substring(#valueof($.stringref),8,10)", - "concat": "#concat(#valueof($.menu.id.file),#valueof($.menu.value.Window))" - }, - "mathresult": { - "add": "#add(#valueof($.numbers[0]),3)", - "subtract": "#subtract(#valueof($.numbers[4]),#valueof($.numbers[0]))", - "multiply": "#multiply(2,#valueof($.numbers[2]))", - "divide": "#divide(9,3)" - }, - "conacted": "#concatall(#valueof($.d))", - "sum": "#sum(#valueof($.numbers))", - "avg": "#average(#valueof($.numbers))", - "min": "#min(#valueof($.numbers))", - "max": "#max(#valueof($.numbers))", - "arrayconacted": "#concatallatpath(#valueof($.x),$.v.a)", - "arraysum": "#sumatpath(#valueof($.x),$.v.c)", - "arrayavg": "#averageatpath(#valueof($.x),$.v.c)", - "arraymin": "#minatpath(#valueof($.x),$.v.b)", - "arraymax": "#maxatpath(#valueof($.x),$.v.b)" - }, - - "iteration": { - "#loop($.numbers)": { - "CurrentValue": "#currentvalue()", - "CurrentIndex": "#currentindex()", - "IsLast": "#ifcondition(#currentindex(),#lastindex(),yes,no)", - "LastValue": "#lastvalue()" - - } - }, - "iteration2": { - "#loop($.x)": { - "CurrentValue": "#currentvalueatpath($.v.a)", - "CurrentIndex": "#currentindex()", - "IsLast": "#ifcondition(#currentindex(),#lastindex(),yes,no)", - "LastValue": "#lastvalueatpath($.v.b)" - - } - }, - "FullName": "#concat(#concat(#concat(#valueof($.Name), ),#concat(#valueof($.MiddleName), )),#valueof($.Surname))", - "Contact Information": { - "Street Name": "#substring(#valueof($.ContactInformation),0,#firstindexof(#valueof($.ContactInformation),:))", - "City": "#substring(#valueof($.ContactInformation),#add(#firstindexof(#valueof($.ContactInformation),:),1),#subtract(#subtract(#lastindexof(#valueof($.ContactInformation),:),#firstindexof(#valueof($.ContactInformation),:)),1))", - "PhoneNumber": "#substring(#valueof($.ContactInformation),#add(#lastindexof(#valueof($.ContactInformation),:),1),#subtract(#lastindexof(#valueof($.ContactInformation),),#lastindexof(#valueof($.ContactInformation),:)))" - }, - "Personal Information": { - "Age": "#substring(#valueof($.PersonalInformation),0,#firstindexof(#valueof($.PersonalInformation),:))", - "Civil Status": "#substring(#valueof($.PersonalInformation),#add(#firstindexof(#valueof($.PersonalInformation),:),1),#subtract(#subtract(#lastindexof(#valueof($.PersonalInformation),:),#firstindexof(#valueof($.PersonalInformation),:)),1))", - "Ethnicity": "#substring(#valueof($.PersonalInformation),#add(#lastindexof(#valueof($.PersonalInformation),:),1),#subtract(#lastindexof(#valueof($.PersonalInformation),),#lastindexof(#valueof($.PersonalInformation),:)))", - "LogId": "#valueof($.LogId)" - }, - "newArray": [ - { - "nr": "1", - "value": "#valueof($.menu.id.file)" - }, - { - "nr": "2", - "value": "#valueof($.menu.id.file)" - }, - { - "nr": "3", - "value": "#valueof($.menu.id.file)" - } - ] -} \ No newline at end of file diff --git a/Examples/Transformer_Existance.json b/Examples/Transformer_Existance.json deleted file mode 100644 index cff52ea..0000000 --- a/Examples/Transformer_Existance.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "BuyDateString": "#ifcondition(#exists($.BuyDate),true,#concat(Buy Date : ,#valueof($.BuyDate)),NotExists)", - "BuyDateString2": "#ifcondition(#existsandnotempty($.BuyDate),true,#concat(Buy Date : ,#valueof($.BuyDate)),EmptyOrNotExists)", - "ExpireDateString": "#ifcondition(#exists($.ExpireDate),true,#concat(Expire Date : ,#valueof($.ExpireDate)),NotExists)", - "ExpireDateString2": "#ifcondition(#existsandnotempty($.ExpireDate),true,#concat(Expire Date : ,#valueof($.ExpireDate)),EmptyOrNotExists)", - "SellDateString": "#ifcondition(#exists($.SellDate),true,#concat(Sell Date : ,#valueof($.SellDate)),NotExists)", - "SellDateString2": "#ifcondition(#existsandnotempty($.SellDate),true,#concat(Sell Date : ,#valueof($.SellDate)),EmptyOrNotExists)" -} \ No newline at end of file diff --git a/Examples/Transformer_Math.json b/Examples/Transformer_Math.json deleted file mode 100644 index ef99f56..0000000 --- a/Examples/Transformer_Math.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "mathresult": { - "add": "#add(#valueof($.numbers[0]),3)", - "subtract": "#subtract(#valueof($.numbers[4]),#valueof($.numbers[0]))", - "multiply": "#multiply(2,#valueof($.numbers[2]))", - "divide": "#divide(9,3)", - "third_element_equals_3": "#ifcondition(#mathequals(#valueof($.numbers[2]),3),true,yes,no)", - "third_element_greaterthan_2": "#ifcondition(#mathgreaterthan(#valueof($.numbers[2]),2),true,yes,no)", - "third_element_lessthan_4": "#ifcondition(#mathlessthan(#valueof($.numbers[2]),4),true,yes,no)", - "third_element_greaterthanorequals_4": "#ifcondition(#mathgreaterthanorequalto(#valueof($.numbers[2]),4),true,yes,no)", - "third_element_lessthanoreuals_2": "#ifcondition(#mathlessthanorequalto(#valueof($.numbers[2]),2),true,yes,no)", - "one_stringequals": "#ifcondition(#stringequals(#valueof($.d[0]),one),true,yes,no)", - "one_stringcontains": "#ifcondition(#stringcontains(#valueof($.d[0]),n),true,yes,no)" - } -} diff --git a/Examples/Transformer_aggregate.json b/Examples/Transformer_aggregate.json deleted file mode 100644 index 2e3d3ac..0000000 --- a/Examples/Transformer_aggregate.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "conacted": "#concatall(#valueof($.d))", - "sum": "#sum(#valueof($.numbers))", - "avg": "#average(#valueof($.numbers))", - "min": "#min(#valueof($.numbers))", - "max": "#max(#valueof($.numbers))" -} diff --git a/Examples/Transformer_array.json b/Examples/Transformer_array.json deleted file mode 100644 index e943566..0000000 --- a/Examples/Transformer_array.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "field": "#valueof($.DataForArrayTransformer.Field1)" - }, - { - "field": "#valueof($.DataForArrayTransformer.Field2)" - } -] \ No newline at end of file diff --git a/Examples/Transformer_arrayaggregate.json b/Examples/Transformer_arrayaggregate.json deleted file mode 100644 index 0687f18..0000000 --- a/Examples/Transformer_arrayaggregate.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "arrayconacted": "#concatallatpath(#valueof($.x),$.v.a)", - "arraysum": "#sumatpath(#valueof($.x),$.v.c)", - "arrayavg": "#averageatpath(#valueof($.x),$.v.c)", - "arraymin": "#minatpath(#valueof($.x),$.v.b)", - "arraymax": "#maxatpath(#valueof($.x),$.v.b)" -} diff --git a/Examples/Transformer_copy.json b/Examples/Transformer_copy.json deleted file mode 100644 index 627be9c..0000000 --- a/Examples/Transformer_copy.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "#": [ "#copy($.menu.id)", "#copy($.menu.value)" ], -} \ No newline at end of file diff --git a/Examples/Transformer_customfunction.json b/Examples/Transformer_customfunction.json deleted file mode 100644 index 39cf35b..0000000 --- a/Examples/Transformer_customfunction.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "Season": "#customfunction(JUST.NET.Test,JUST.NET.Test.Season.findseason,#valueof($.tree.branch.leaf),#valueof($.tree.branch.flower))" -} diff --git a/Examples/Transformer_customfunctionspecial.json b/Examples/Transformer_customfunctionspecial.json deleted file mode 100644 index fbe54fc..0000000 --- a/Examples/Transformer_customfunctionspecial.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "Season": "#customfunction(JUST.NET.Test,JUST.NET.Test.Season.serialize,#valueof($))" -} \ No newline at end of file diff --git a/Examples/Transformer_delete.json b/Examples/Transformer_delete.json deleted file mode 100644 index 29127ab..0000000 --- a/Examples/Transformer_delete.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "#": [ "#copy($)", "#delete($.menu.popup)", "#delete($.x)" ] -} diff --git a/Examples/Transformer_externalmethods.json b/Examples/Transformer_externalmethods.json deleted file mode 100644 index 9da4549..0000000 --- a/Examples/Transformer_externalmethods.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "externalStaticMethodResult": "#ExternalMethods::ExternalMethods.ExternalClass::StaticMethod()", - "externalStaticTypedParametersResult": "#ExternalMethods::ExternalMethods.ExternalClass::StaticTypedParameters(1,true,abc,2018-10-11T11:00:00.000Z)", - "externalInstanceMethodResult": "#ExternalMethods::ExternalMethods.ExternalClass::InstanceMethod()", - "externalInstanceTypedParametersResult": "#ExternalMethods::ExternalMethods.ExternalClass::TypedParameters(1,true,abc,2018-10-11T11:00:00.000Z)", - "externalInstanceNavigateTypedParametersResult": "#ExternalMethods::ExternalMethods.ExternalClass::NavigateTypedParameters(#valueof($.season.characteristics.hot))", - - "internalStaticMethodResult": "#InternalMethods.InternalClass::StaticMethod()", - "internalStaticTypedParametersResult": "#InternalMethods.InternalClass::StaticTypedParameters(1,true,abc,2018-10-11T11:00:00.000Z)", - "internalInstanceMethodResult": "#InternalMethods.InternalClass::InstanceMethod()", - "internalInstanceTypedParametersResult": "#InternalMethods.InternalClass::TypedParameters(1,true,abc,2018-10-11T11:00:00.000Z)", - "internalInstanceNavigateTypedParametersResult": "#InternalMethods.InternalClass::NavigateTypedParameters(#valueof($.season))", - - "summer": "#ExternalMethods::SeasonsHelper.Season::IsSummer(#valueof($.season.characteristics.hot),#valueof($.season.characteristics.averageDaysOfRain),#valueof($.season.characteristics.randomDay))" -} diff --git a/Examples/Transformer_ifcondition.json b/Examples/Transformer_ifcondition.json deleted file mode 100644 index 873ea7d..0000000 --- a/Examples/Transformer_ifcondition.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "ifconditiontesttrue": "#ifcondition(#valueof($.menu.id.file),csv,#valueof($.menu.value.Window),fail)", - "ifconditiontestfalse": "#ifcondition(#valueof($.menu.id.file),xml,#valueof($.menu.value.Window),fail)" -} diff --git a/Examples/Transformer_looping.json b/Examples/Transformer_looping.json deleted file mode 100644 index caf6595..0000000 --- a/Examples/Transformer_looping.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - - "iteration": { - "#loop($.numbers)": { - "CurrentValue": "#currentvalue()", - "CurrentIndex": "#currentindex()", - "IsLast": "#ifcondition(#currentindex(),#lastindex(),yes,no)", - "LastValue": "#lastvalue()" - - } - }, - "iteration2": { - "#loop($.x)": { - "CurrentValue": "#currentvalueatpath($.v.a)", - "CurrentIndex": "#currentindex()", - "IsLast": "#ifcondition(#currentindex(),#lastindex(),yes,no)", - "LastValue": "#lastvalueatpath($.v.b)" - - } - }, - "othervalue": "othervalue" -} diff --git a/Examples/Transformer_looptests.json b/Examples/Transformer_looptests.json deleted file mode 100644 index f69e6ef..0000000 --- a/Examples/Transformer_looptests.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "iPhoneNumbers1": { - "#loop($.people[*].phoneNumbers[?(@.type=='iPhone')])": { - "phoneNumber": "#concat(#currentvalueatpath($.countryPrefix), #currentvalueatpath($.number))" - } - }, - "iPhoneNumbers2": { - "#loop($.people[?(@.name=='Jim' || @.name=='John')].phoneNumbers[?(@.type=='iPhone')])": { - "phoneNumber": "#concat(#currentvalueatpath($.countryPrefix), #currentvalueatpath($.number))" - } - }, - "iPhoneNumbers3": { - "#loop($.people[?(@.name=='Jim1' || @.name=='John')].phoneNumbers[?(@.type=='iPhone')])": { - "phoneNumber": "#concat(#currentvalueatpath($.countryPrefix), #currentvalueatpath($.number))" - } - }, - "iPhoneNumbers4": { - "#loop($.people[?(@.name=='Jim1' || @.name=='John1')].phoneNumbers[?(@.type=='iPhone')])": { - "phoneNumber": "#concat(#currentvalueatpath($.countryPrefix), #currentvalueatpath($.number))" - } - }, - "iPhoneNumbers5": { - "#loop($.people[*].phoneNumbers[?(@.type== '#valueof($.PhoneTypeToSearch)')])": { - "phoneNumber": "#concat(#currentvalueatpath($.countryPrefix), #currentvalueatpath($.number))" - } - } -} \ No newline at end of file diff --git a/Examples/Transformer_nestedfunctions.json b/Examples/Transformer_nestedfunctions.json deleted file mode 100644 index d9accf0..0000000 --- a/Examples/Transformer_nestedfunctions.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "FullName": "#concat(#concat(#concat(#valueof($.Name), ),#concat(#valueof($.MiddleName), )),#valueof($.Surname))", - "Contact Information": { - "Street Name": "#substring(#valueof($.ContactInformation),0,#firstindexof(#valueof($.ContactInformation),:))", - "City": "#substring(#valueof($.ContactInformation),#add(#firstindexof(#valueof($.ContactInformation),:),1),#subtract(#subtract(#lastindexof(#valueof($.ContactInformation),:),#firstindexof(#valueof($.ContactInformation),:)),1))", - "PhoneNumber": "#substring(#valueof($.ContactInformation),#add(#lastindexof(#valueof($.ContactInformation),:),1),#subtract(#lastindexof(#valueof($.ContactInformation),),#lastindexof(#valueof($.ContactInformation),:)))" - }, - "Personal Information": { - "Age": "#substring(#valueof($.PersonalInformation),0,#firstindexof(#valueof($.PersonalInformation),:))", - "Civil Status": "#substring(#valueof($.PersonalInformation),#add(#firstindexof(#valueof($.PersonalInformation),:),1),#subtract(#subtract(#lastindexof(#valueof($.PersonalInformation),:),#firstindexof(#valueof($.PersonalInformation),:)),1))", - "Ethnicity": "#substring(#valueof($.PersonalInformation),#add(#lastindexof(#valueof($.PersonalInformation),:),1),#subtract(#lastindexof(#valueof($.PersonalInformation),),#lastindexof(#valueof($.PersonalInformation),:)))" - } -} diff --git a/Examples/Transformer_nestedloop.json b/Examples/Transformer_nestedloop.json deleted file mode 100644 index 99efe80..0000000 --- a/Examples/Transformer_nestedloop.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "hello": { - "#loop($.NestedLoop.Organization.Employee)": { - "CurrentName": "#currentvalueatpath($.Name)", - "Details": { - "#loopwithincontext($.Details)": { - "CurrentCountry": "#currentvalueatpath($.Country)" - } - } - } - } -} \ No newline at end of file diff --git a/Examples/Transformer_replace.json b/Examples/Transformer_replace.json deleted file mode 100644 index 3e1ff0a..0000000 --- a/Examples/Transformer_replace.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "#": [ "#copy($)", "#replace($.menu.id,#valueof($.menu.value))" ] -} \ No newline at end of file diff --git a/Examples/Transformer_string.json b/Examples/Transformer_string.json deleted file mode 100644 index adf1e1f..0000000 --- a/Examples/Transformer_string.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "stringresult": { - "lastindexofand": "#lastindexof(#valueof($.stringref),and)", - "firstindexofand": "#firstindexof(#valueof($.stringref),and)", - "subsrting": "#substring(#valueof($.stringref),8,10)", - "concat": "#concat(#valueof($.menu.id.file),#valueof($.menu.value.Window))" - } -} diff --git a/Examples/Transformer_valueof.json b/Examples/Transformer_valueof.json deleted file mode 100644 index 828c74c..0000000 --- a/Examples/Transformer_valueof.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "root": { - "menu1": "#valueof($.menu.popup.menuitem[?(@.value=='New')].onclick)", - "menu2": "#valueof($.menu.popup.menuitem[?(@.value=='Open')].onclick)" - }, - -} \ No newline at end of file diff --git a/Examples/Transformer_valueofarray.json b/Examples/Transformer_valueofarray.json deleted file mode 100644 index 96c907a..0000000 --- a/Examples/Transformer_valueofarray.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "root": { - "array": { - - "fullarray": "#valueof($.x)", - "arrayelement": "#valueof($.x[0])", - "specificelement": "#valueof($.x[1].v.a)" - } - } - -} diff --git a/Examples/Transformer_xfunctions.json b/Examples/Transformer_xfunctions.json deleted file mode 100644 index 8f4e940..0000000 --- a/Examples/Transformer_xfunctions.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "FullName": "#xconcat(#valueof($.Name),#constant_comma(),#valueof($.MiddleName),#constant_comma(),#valueof($.Surname))", - "AgeOfParents": "#xadd(#valueof($.AgeOfMother),#valueof($.AgeOfFather))" -} \ No newline at end of file diff --git a/Examples/ValidationInput.json b/Examples/ValidationInput.json deleted file mode 100644 index 4daa776..0000000 --- a/Examples/ValidationInput.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "x.tree": { "x.branch": { "x.leaf": "1" } }, - "x.child": "1", - "y.animal": "1" -} diff --git a/ExternalMethods/ExternalClass.cs b/ExternalMethods/ExternalClass.cs deleted file mode 100644 index 986ee6f..0000000 --- a/ExternalMethods/ExternalClass.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Newtonsoft.Json.Linq; -using System; - -namespace ExternalMethods -{ - public class ExternalClass - { - public static string StaticMethod() - { - return "External Static"; - } - - public string InstanceMethod() - { - return "External Instance"; - } - - public string StaticTypedParameters(int n, bool b, string s, DateTime d) - { - return "External Static TypedParameters success"; - } - - public string TypedParameters(int n, bool b, string s, DateTime d) - { - return "External TypedParameters success"; - } - - public string NavigateTypedParameters(bool val) - { - return val.ToString(); - } - } -} diff --git a/ExternalMethods/ExternalMethods.csproj b/ExternalMethods/ExternalMethods.csproj deleted file mode 100644 index 6e86919..0000000 --- a/ExternalMethods/ExternalMethods.csproj +++ /dev/null @@ -1,11 +0,0 @@ - - - - netstandard2.0 - - - - - - - diff --git a/ExternalMethods/Season.cs b/ExternalMethods/Season.cs deleted file mode 100644 index 28e35cb..0000000 --- a/ExternalMethods/Season.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace SeasonsHelper -{ - public class Season - { - public static bool IsSummer(bool hot, int averageDaysOfRain, DateTime randomDay) - { - return hot && averageDaysOfRain < 20 && randomDay > new DateTime(2018, 6, 21); - } - } -} diff --git a/JUST.NET.sln b/JUST.NET.sln index 1e77d31..e3bf876 100644 --- a/JUST.NET.sln +++ b/JUST.NET.sln @@ -5,15 +5,13 @@ VisualStudioVersion = 16.0.30413.136 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JUST.net", "JUST.net\JUST.net.csproj", "{C33053BC-A3F2-4F0A-9B7F-B0AF5AD4EFFB}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExternalMethods", "ExternalMethods\ExternalMethods.csproj", "{15F60FAC-38CF-4AA7-B369-E738702AA94E}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ENV", "ENV", "{FF566713-3F06-4A89-9127-1916A9DB3C3E}" ProjectSection(SolutionItems) = preProject azure-pipelines.yml = azure-pipelines.yml README.md = README.md EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JUST.Net.Test", "JUST.Net.Test\JUST.Net.Test.csproj", "{4D2D7084-412B-4782-A687-BA2C22D3D14B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JUST.Net.Test", "JUST.Net.Test\JUST.Net.Test.csproj", "{4D2D7084-412B-4782-A687-BA2C22D3D14B}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -25,10 +23,6 @@ Global {C33053BC-A3F2-4F0A-9B7F-B0AF5AD4EFFB}.Debug|Any CPU.Build.0 = Debug|Any CPU {C33053BC-A3F2-4F0A-9B7F-B0AF5AD4EFFB}.Release|Any CPU.ActiveCfg = Release|Any CPU {C33053BC-A3F2-4F0A-9B7F-B0AF5AD4EFFB}.Release|Any CPU.Build.0 = Release|Any CPU - {15F60FAC-38CF-4AA7-B369-E738702AA94E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {15F60FAC-38CF-4AA7-B369-E738702AA94E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {15F60FAC-38CF-4AA7-B369-E738702AA94E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {15F60FAC-38CF-4AA7-B369-E738702AA94E}.Release|Any CPU.Build.0 = Release|Any CPU {4D2D7084-412B-4782-A687-BA2C22D3D14B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4D2D7084-412B-4782-A687-BA2C22D3D14B}.Debug|Any CPU.Build.0 = Debug|Any CPU {4D2D7084-412B-4782-A687-BA2C22D3D14B}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/JUST.net/ExpressionInterpreter.cs b/JUST.net/ExpressionInterpreter.cs index 158bc3d..9c55905 100644 --- a/JUST.net/ExpressionInterpreter.cs +++ b/JUST.net/ExpressionInterpreter.cs @@ -91,6 +91,14 @@ public void SetContext(JToken arrayElement, JArray array, string expression) case "lastIndex": SetVariable("lastIndex", array.IndexOf(array.Last)); break; + + case "arrayElementStr": + { + if (arrayElement == null) + SetVariable("currentElementStr", arrayElement.ToString()); + SetVariable("currentElementStr", arrayElement.ToString()); + } + break; } } } diff --git a/JUST.net/Transformer.cs b/JUST.net/Transformer.cs index b1cf6e2..c92e038 100644 --- a/JUST.net/Transformer.cs +++ b/JUST.net/Transformer.cs @@ -6,7 +6,7 @@ namespace JUST { - internal class Transformer + internal static class Transformer { public static object ValueOf(string jsonPath, JToken input, bool strictPathHandling, object defaultValue) { @@ -23,11 +23,6 @@ public static object ValueOf(string jsonPath, JToken input, bool strictPathHandl return GetValue(selectedToken, defaultValue); } - public static string getcurrentscopeasstring(string inputJson) - { - return inputJson; - } - public static object getarray(string document, string jsonPath, string inputJson) { JsonReader reader = new JsonTextReader(new StringReader(document)) @@ -101,25 +96,6 @@ public static string lastindexof(string stringRef, string searchString, string i return stringRef.LastIndexOf(searchString).ToString(); } - public static string concatall(string array, string inputJson) - { - string result = null; - - JArray parsedArray = Utilities.ParseOrGetEmpty(array); - - if (parsedArray != null) - { - foreach (JToken token in parsedArray.Children()) - { - if (result == null) - result = string.Empty; - result += token.ToString(); - } - } - - return result; - } - public static string listall(string array, string separator, string inputJson) { string result = null; @@ -149,32 +125,6 @@ public static string listall(string array, string separator, string inputJson) return result; } - public static string concatallatpath(string array, string jsonPath, string inputJson) - { - string result = null; - - JArray parsedArray = Utilities.ParseOrGetEmpty(array); - - if (parsedArray != null) - { - - foreach (JToken token in parsedArray.Children()) - { - JToken selectedToken = token.SelectToken(jsonPath); - - if (selectedToken == null) - continue; - - if (result == null) - result = string.Empty; - - result += selectedToken.ToString(); - } - } - - return result; - } - public static string listallatpath(string array, string jsonPath, string separator, string inputJson) { string result = null; @@ -209,34 +159,6 @@ public static string listallatpath(string array, string jsonPath, string separat } #endregion - #region math functions - - - public static string add(string num1, string num2, string inputJson) - { - try - { - return (Convert.ToInt32(num1) + Convert.ToInt32(num2)).ToString(); - } - catch { return null; } - } - public static string subtract(string num1, string num2, string inputJson) - { - try { return (Convert.ToInt32(num1) - Convert.ToInt32(num2)).ToString(); } - catch { return null; } - } - public static string multiply(string num1, string num2, string inputJson) - { - try { return (Convert.ToInt32(num1) * Convert.ToInt32(num2)).ToString(); } - catch { return null; } - } - public static string divide(string num1, string num2, string inputJson) - { - try { return (Convert.ToInt32(num1) / Convert.ToInt32(num2)).ToString(); } - catch { return null; } - } - #endregion - #region aggregate functions public static object count(string array, string inputJson) { @@ -524,16 +446,6 @@ public static string arraylength(string array, string inputJson) #endregion - // #region arraylooping - // public static object lastvalueatpath(JArray array, JToken currentElement, string jsonPath) - // { - // - // JToken selectedToken = array.Last.SelectToken(jsonPath); - // - // return GetValue(selectedToken); - // } - // #endregion - public static object GetValue(JToken selectedToken, object defaultValue) { object output = defaultValue; From 454cd0e59cdeafe64b68f46d0974055d4ba6aace Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Mon, 7 Sep 2020 10:15:27 +0200 Subject: [PATCH 36/43] Remove demo classes --- InternalClass.cs | 33 --------------------------------- Season.cs | 42 ------------------------------------------ 2 files changed, 75 deletions(-) delete mode 100644 InternalClass.cs delete mode 100644 Season.cs diff --git a/InternalClass.cs b/InternalClass.cs deleted file mode 100644 index a8cfb3c..0000000 --- a/InternalClass.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Newtonsoft.Json.Linq; -using System; - -namespace InternalMethods -{ - public class InternalClass - { - public static string StaticMethod() - { - return "Internal Static"; - } - - public string InstanceMethod() - { - return "Internal Instance"; - } - - public string StaticTypedParameters(int n, bool b, string s, DateTime d) - { - return "Internal Static TypedParameters success"; - } - - public string TypedParameters(int n, bool b, string s, DateTime d) - { - return "Internal TypedParameters success"; - } - - public string NavigateTypedParameters(JObject token) - { - return token.ToString(); - } - } -} diff --git a/Season.cs b/Season.cs deleted file mode 100644 index 57167a5..0000000 --- a/Season.cs +++ /dev/null @@ -1,42 +0,0 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace JUST.NET.Test -{ - public class Season - { - public static string findseason(string leafColour, string flowerColour) - { - if (leafColour == "green" && flowerColour == "red") - return "summer"; - else - return "winter"; - } - - public static object serialize(string inObj) - { - JObject jObj = JObject.FromObject( JsonConvert.DeserializeObject(inObj)); - - JArray array = new JArray(); - - foreach(JProperty property in jObj.Children()) - { - JObject nameValObj = new JObject(); - nameValObj.Add("name", property.Name); - nameValObj.Add("value", property.Value); - - array.Add(nameValObj); - } - - JObject returnObj = new JObject(); - returnObj.Add("namevaluecollection",array); - - return returnObj; - } - } -} From d78470bd097d07a5c9ec9f47512ac8a77bbd4bd6 Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Mon, 7 Sep 2020 13:19:43 +0200 Subject: [PATCH 37/43] Remove not required code --- JUST.net/JsonTransformer.cs | 61 ++++++-------------- JUST.net/JsonValidator.cs | 4 +- JUST.net/ReflectionHelper.cs | 107 ----------------------------------- 3 files changed, 17 insertions(+), 155 deletions(-) delete mode 100644 JUST.net/ReflectionHelper.cs diff --git a/JUST.net/JsonTransformer.cs b/JUST.net/JsonTransformer.cs index 2552fe7..769b733 100644 --- a/JUST.net/JsonTransformer.cs +++ b/JUST.net/JsonTransformer.cs @@ -701,21 +701,22 @@ private object ParseFunction(string functionString, string inputJson, JArray arr output = newArray; } - else if (functionName == "currentvalue" || functionName == "currentindex" || functionName == "lastindex" - || functionName == "lastvalue") - output = ReflectionHelper.InvokeFunction(null, "JUST.Transformer", functionName, new object[] { array, currentArrayElement }); - else if (functionName == "currentvalueatpath" || functionName == "lastvalueatpath") - output = ReflectionHelper.InvokeFunction(null, "JUST.Transformer", functionName, new object[] { array, currentArrayElement, arguments[0] }); - else if (functionName == "customfunction") - output = CallCustomFunction(parameters); - else - { - if (currentArrayElement != null && functionName != "valueof") - { - parameters[i] = JsonConvert.SerializeObject(currentArrayElement); - } - output = ReflectionHelper.InvokeFunction(null, DefaultTransformerNamespace, functionName, parameters); - } + // TODO: Remove + ///else if (functionName == "currentvalue" || functionName == "currentindex" || functionName == "lastindex" + /// || functionName == "lastvalue") + /// output = ReflectionHelper.InvokeFunction(null, "JUST.Transformer", functionName, new object[] { array, currentArrayElement }); + ///else if (functionName == "currentvalueatpath" || functionName == "lastvalueatpath") + /// output = ReflectionHelper.InvokeFunction(null, "JUST.Transformer", functionName, new object[] { array, currentArrayElement, arguments[0] }); + ///else if (functionName == "customfunction") + /// output = CallCustomFunction(parameters); + ///else + ///{ + /// if (currentArrayElement != null && functionName != "valueof") + /// { + /// parameters[i] = JsonConvert.SerializeObject(currentArrayElement); + /// } + /// output = ReflectionHelper.InvokeFunction(null, DefaultTransformerNamespace, functionName, parameters); + ///} return output; } @@ -724,36 +725,6 @@ private object ParseFunction(string functionString, string inputJson, JArray arr throw new Exception("Error while calling function : " + functionString + " - " + ex.Message, ex); } } - - private object CallCustomFunction(object[] parameters) - { - object[] customParameters = new object[parameters.Length - 3]; - string functionString = string.Empty; - string dllName = string.Empty; - int i = 0; - foreach (object parameter in parameters) - { - if (i == 0) - dllName = parameter.ToString(); - else if (i == 1) - functionString = parameter.ToString(); - else - if (i != (parameters.Length - 1)) - customParameters[i - 2] = parameter; - - i++; - } - - int index = functionString.LastIndexOf("."); - - string className = functionString.Substring(0, index); - string functionName = functionString.Substring(index + 1, functionString.Length - index - 1); - - className = className + "," + dllName; - - return ReflectionHelper.InvokeFunction(null, className, functionName, customParameters); - - } #endregion #region GetArguments diff --git a/JUST.net/JsonValidator.cs b/JUST.net/JsonValidator.cs index e09f7a6..d62a2b8 100644 --- a/JUST.net/JsonValidator.cs +++ b/JUST.net/JsonValidator.cs @@ -116,9 +116,7 @@ private static void PrefixKey(JObject jo, string prefix) private static void HandleEvent(object sender, SchemaValidationEventArgs args) { - throw new Exception( args.Message); - + throw new Exception( args.Message); } - } } diff --git a/JUST.net/ReflectionHelper.cs b/JUST.net/ReflectionHelper.cs deleted file mode 100644 index aa73399..0000000 --- a/JUST.net/ReflectionHelper.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text.RegularExpressions; - -namespace JUST -{ - internal class ReflectionHelper - { - internal static object InvokeFunction(Assembly assembly, String myclass, String mymethod, object[] parameters, bool convertParameters = false) - { - Type type = assembly?.GetType(myclass) ?? Type.GetType(myclass); - MethodInfo methodInfo = type.GetTypeInfo().GetMethod(mymethod); - var instance = !methodInfo.IsStatic ? Activator.CreateInstance(type) : null; - - var typedParameters = new List(); - if (convertParameters) - { - var parameterInfos = methodInfo.GetParameters(); - for (int i = 0; i < parameterInfos.Length; i++) - { - var pType = parameterInfos[i].ParameterType; - typedParameters.Add(GetTypedValue(pType, parameters[i])); - } - } - return methodInfo.Invoke(instance, convertParameters ? typedParameters.ToArray() : parameters); - } - - private static Assembly GetAssembly(bool isAssemblyDefined, string assemblyName, string namespc, string methodName) - { - var assemblies = AppDomain.CurrentDomain.GetAssemblies(); - if (isAssemblyDefined) - { - var assemblyFileName = !assemblyName.EndsWith(".dll") ? $"{assemblyName}.dll" : assemblyName; - var assembly = assemblies.SingleOrDefault(a => a.ManifestModule.Name == assemblyFileName); - if (assembly == null) - { - var assemblyLocation = Path.Combine(Directory.GetCurrentDirectory(), assemblyFileName); - assembly = Assembly.LoadFile(assemblyLocation); - AppDomain.CurrentDomain.Load(assembly.GetName()); - } - - return assembly; - } - else - { - foreach (var assembly in assemblies.Where(a => !a.FullName.StartsWith("System."))) - { - Type[] types = null; - try - { - types = assembly.GetTypes(); - } - catch (ReflectionTypeLoadException ex) - { - types = ex.Types; - } - - foreach (var typeInfo in types) - { - if (string.Compare(typeInfo.FullName, namespc, StringComparison.InvariantCultureIgnoreCase) == 0) - { - return assembly; - } - } - } - } - return null; - } - - private static object[] FilterParameters(object[] parameters) - { - if (string.IsNullOrEmpty(parameters[0]?.ToString() ?? string.Empty)) - { - parameters = parameters.Skip(1).ToArray(); - } - if (parameters.Length > 0 && parameters.Last().ToString() == "{}") - { - parameters = parameters.Take(parameters.Length - 1).ToArray(); - } - return parameters; - } - - private static object GetTypedValue(Type pType, object val) - { - object typedValue = val; - var converter = TypeDescriptor.GetConverter(pType); - if (converter.CanConvertFrom(val.GetType())) - { - typedValue = converter.ConvertFrom(val); - } - else if (pType.IsPrimitive) - { - typedValue = Convert.ChangeType(val, pType); - } - else if (!pType.IsAbstract) - { - var parse = pType.GetMethod("Parse", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(string) }, null); - typedValue = parse?.Invoke(null, new[] { val }) ?? pType.GetConstructor(new[] { typeof(string) })?.Invoke(new[] { val }) ?? val; - } - return typedValue; - } - } -} From 1bcb2224a3a453f6fa5494c4790bd0cbc026703d Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Mon, 18 Jul 2022 12:07:07 +0200 Subject: [PATCH 38/43] Add simple regex implementation --- JUST.Net.Test/DynamicExpressionRegexTest.cs | 37 +++++++++++++++++++++ JUST.Net.Test/JUST.Net.Test.csproj | 2 +- JUST.net/ExpressionInterpreter.cs | 12 +++++++ JUST.net/JsonTransformer.cs | 2 ++ 4 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 JUST.Net.Test/DynamicExpressionRegexTest.cs diff --git a/JUST.Net.Test/DynamicExpressionRegexTest.cs b/JUST.Net.Test/DynamicExpressionRegexTest.cs new file mode 100644 index 0000000..da663be --- /dev/null +++ b/JUST.Net.Test/DynamicExpressionRegexTest.cs @@ -0,0 +1,37 @@ +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace JUST.Net.Test +{ + public class DynamicExpressionRegexTest + { + [Fact] + public void SimpleNumber_Test() + { + var input = @"{ }"; + var transformer = @"{ ""rg"": ""~(regex(\""V-12345\"", \""@@\\d+\"", \""0\""))"" }"; + + var jsonTransformer = new JsonTransformer(); + var result = jsonTransformer.Transform(transformer, input); + + var obj = JObject.Parse(result); + Assert.Equal("12345", obj.SelectToken("$.rg").Value()); + } + + [Fact] + public void SimpleNumber_Test_Defaukt() + { + var input = @"{ }"; + var transformer = @"{ ""rg"": ""~(regex(\""VHHG\"", \""d+\"", \""111\""))"" }"; + + var jsonTransformer = new JsonTransformer(); + var result = jsonTransformer.Transform(transformer, input); + + var obj = JObject.Parse(result); + Assert.Equal("111", obj.SelectToken("$.rg").Value()); + } + } +} diff --git a/JUST.Net.Test/JUST.Net.Test.csproj b/JUST.Net.Test/JUST.Net.Test.csproj index 83a1c9c..0a14dc5 100644 --- a/JUST.Net.Test/JUST.Net.Test.csproj +++ b/JUST.Net.Test/JUST.Net.Test.csproj @@ -1,7 +1,7 @@ - netcoreapp3.1 + net6.0 false diff --git a/JUST.net/ExpressionInterpreter.cs b/JUST.net/ExpressionInterpreter.cs index 9c55905..b65cf3c 100644 --- a/JUST.net/ExpressionInterpreter.cs +++ b/JUST.net/ExpressionInterpreter.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Text.RegularExpressions; namespace JUST.net { @@ -23,6 +24,7 @@ public ExpressionInterpreter() Reference(typeof(DateTime)); Reference(typeof(String)); Reference(typeof(Convert)); + Reference(typeof(Regex)); } /// @@ -46,11 +48,21 @@ public void Setup(JToken inputObject, bool strictPathHandling) }; Func nullToString = (value) => value ?? ""; + Func regex= (value, pattern, defaultValue) => + { + var result = Regex.Match(value, pattern); + if (result.Success) + return result.Value; + + return defaultValue; + }; + SetFunction("valueOf", valueOf); SetFunction("valueOfStr", valueOfStr); SetFunction("valueOfInt", valueOfInt); SetFunction("valueOfDouble", valueOfDouble); SetFunction("nullToString", nullToString); + SetFunction("regex", regex); } /// diff --git a/JUST.net/JsonTransformer.cs b/JUST.net/JsonTransformer.cs index 769b733..446774d 100644 --- a/JUST.net/JsonTransformer.cs +++ b/JUST.net/JsonTransformer.cs @@ -205,6 +205,8 @@ private void RecursiveEvaluate(JToken parentToken, string inputJson, JArray pare try { + expression = expression.Replace("@@\\", @"\\"); + var result = expressionInterpreter.Eval(expression); property.Value = new JValue(result); } From c50eb35507a93ce4d9ea7d40650245413ca31e5d Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Mon, 18 Jul 2022 12:08:31 +0200 Subject: [PATCH 39/43] Update version number --- JUST.net/JUST.net.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/JUST.net/JUST.net.csproj b/JUST.net/JUST.net.csproj index 44846bc..e37d6f9 100644 --- a/JUST.net/JUST.net.csproj +++ b/JUST.net/JUST.net.csproj @@ -14,9 +14,9 @@ This will repace the JUST and JUST.NETCore packages. Fixed the following issues:- https://github.com/WorkMaze/JUST.net/issues/26 https://github.com/WorkMaze/JUST.net/issues/25 - 5.8.420.825 - 5.8.420.825 - 5.8.420 + 5.6.22.718 + 5.6.22.718 + 5.6.22 From e40903ad851e7a2eefa5910100357b59659eaa28 Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Thu, 5 Sep 2024 11:21:13 +0200 Subject: [PATCH 40/43] Enable if-group --- JUST.net/JsonTransformer.cs | 41 +++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/JUST.net/JsonTransformer.cs b/JUST.net/JsonTransformer.cs index 446774d..e9e3abe 100644 --- a/JUST.net/JsonTransformer.cs +++ b/JUST.net/JsonTransformer.cs @@ -277,20 +277,45 @@ private void RecursiveEvaluate(JToken parentToken, string inputJson, JArray pare int endIndex = property.Name.LastIndexOf(")"); string functionString = property.Name.Substring(startIndex + 1, endIndex - startIndex - 1); - - object functionResult = ParseFunction(functionString, inputJson, null, null); bool result = false; - try + if (ExpressionParserUtilities.IsExpression(functionString, out string exp)) { - result = Convert.ToBoolean(functionResult); + try + { + expression = expression.Replace("@@\\", @"\\"); + + try + { + result = (bool)expressionInterpreter.Eval(expression); + } + catch (Exception ex) + { + throw new Exception("#ifgroup expression can only handle boolean data types. E.g. ~(1 == 1)", ex); + } + } + catch (PathNotFoundException ex) + { + throw; + } + catch (Exception ex) + { + throw new Exception($"Could not execute expression: {expression}. Property: {property}.", ex); + } } - catch + else { - result = false; - } - + object functionResult = ParseFunction(functionString, inputJson, null, null); + try + { + result = Convert.ToBoolean(functionResult); + } + catch + { + result = false; + } + } if (result == true) { From c9e5ba95d06b804ab87d8f30209f563b23c9c4f7 Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Thu, 5 Sep 2024 11:25:11 +0200 Subject: [PATCH 41/43] Fix NRE --- JUST.net/JsonTransformer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/JUST.net/JsonTransformer.cs b/JUST.net/JsonTransformer.cs index e9e3abe..c88418d 100644 --- a/JUST.net/JsonTransformer.cs +++ b/JUST.net/JsonTransformer.cs @@ -283,11 +283,11 @@ private void RecursiveEvaluate(JToken parentToken, string inputJson, JArray pare { try { - expression = expression.Replace("@@\\", @"\\"); + exp = exp.Replace("@@\\", @"\\"); try { - result = (bool)expressionInterpreter.Eval(expression); + result = (bool)expressionInterpreter.Eval(exp); } catch (Exception ex) { From 7b3fe6bd4a1979e9f891c0ecd3b1a24e8b5d8618 Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Thu, 5 Sep 2024 11:26:57 +0200 Subject: [PATCH 42/43] Increase version --- JUST.net/JUST.net.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/JUST.net/JUST.net.csproj b/JUST.net/JUST.net.csproj index e37d6f9..85fc1bf 100644 --- a/JUST.net/JUST.net.csproj +++ b/JUST.net/JUST.net.csproj @@ -14,9 +14,9 @@ This will repace the JUST and JUST.NETCore packages. Fixed the following issues:- https://github.com/WorkMaze/JUST.net/issues/26 https://github.com/WorkMaze/JUST.net/issues/25 - 5.6.22.718 - 5.6.22.718 - 5.6.22 + 6.0.24.905 + 6.0.24.905 + 6.0.24 From 1bca66afebc911d17b2f61bb7edf5b99dcd9533d Mon Sep 17 00:00:00 2001 From: Benedikt Eggers Date: Wed, 2 Apr 2025 17:48:38 +0200 Subject: [PATCH 43/43] Add createSplitList --- JUST.net/ExpressionInterpreter.cs | 16 +++++++++++++++- JUST.net/JsonTransformer.cs | 14 +++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/JUST.net/ExpressionInterpreter.cs b/JUST.net/ExpressionInterpreter.cs index b65cf3c..18e4b37 100644 --- a/JUST.net/ExpressionInterpreter.cs +++ b/JUST.net/ExpressionInterpreter.cs @@ -31,6 +31,7 @@ public ExpressionInterpreter() /// Initialize core methods /// public void Setup(JToken inputObject, bool strictPathHandling) + { this.strictPathHandling = strictPathHandling; @@ -48,7 +49,7 @@ public void Setup(JToken inputObject, bool strictPathHandling) }; Func nullToString = (value) => value ?? ""; - Func regex= (value, pattern, defaultValue) => + Func regex = (value, pattern, defaultValue) => { var result = Regex.Match(value, pattern); if (result.Success) @@ -57,11 +58,24 @@ public void Setup(JToken inputObject, bool strictPathHandling) return defaultValue; }; + Func createSplitList = (value, separator) => + { + if (value == null) + return new JArray(); + + if (separator == null) + throw new Exception("createSplitList two paramters (value, separator)"); + + var splits = value.Split(new string[] { separator }, StringSplitOptions.RemoveEmptyEntries); + return JArray.FromObject(splits); + }; + SetFunction("valueOf", valueOf); SetFunction("valueOfStr", valueOfStr); SetFunction("valueOfInt", valueOfInt); SetFunction("valueOfDouble", valueOfDouble); SetFunction("nullToString", nullToString); + SetFunction("createSplitList", createSplitList); SetFunction("regex", regex); } diff --git a/JUST.net/JsonTransformer.cs b/JUST.net/JsonTransformer.cs index c88418d..6e4724e 100644 --- a/JUST.net/JsonTransformer.cs +++ b/JUST.net/JsonTransformer.cs @@ -208,7 +208,19 @@ private void RecursiveEvaluate(JToken parentToken, string inputJson, JArray pare expression = expression.Replace("@@\\", @"\\"); var result = expressionInterpreter.Eval(expression); - property.Value = new JValue(result); + + if (result is JArray arrayValue) + { + property.Value = arrayValue; + continue; // Skip further processing + } + if (result is JObject jObject) + { + property.Value = jObject; + continue; // Skip further processing + } + else + property.Value = new JValue(result); } catch (PathNotFoundException ex) {