我有什么 我有存储在数据库中的模板,以及在C#中转换为字典的JSON数据。
示例:
模板:“嗨{FirstName}”
数据:“{FirstName:'Jack'}”
通过使用正则表达式提取模板中{}内的任何内容,可以轻松处理一级数据。
我想要什么 我希望能够更深入地了解JSON而不是第一层。
示例:
模板:“嗨{姓名:{First}}”
数据:“{Name:{First:'Jack',Last:'Smith'}}”
我应该采取什么方法? (以及从哪个选择开始的一些指导)
我也希望能够遍历模板中的数据,但我根本不知道从哪一个开始!
谢谢堆
答案 0 :(得分:4)
你很幸运! SmartFormat完全按照您的描述完成。它是一个轻量级的开源字符串格式化实用程序。
它支持命名占位符:
var template = " {Name:{Last}, {First}} ";
var data = new { Name = new { First="Dwight", Last="Schrute" } };
var result = Smart.Format(template, data);
// Outputs: " Schrute, Dwight " SURPRISE!
它还支持列表格式:
var template = " {People:{}|, |, and} ";
var data = new { People = new[]{ "Dwight", "Michael", "Jim", "Pam" } };
var result = Smart.Format(template, data);
// Outputs: " Dwight, Michael, Jim, and Pam "
您可以查看Named Placeholders和List Formatter的单元测试,以查看更多示例!
它甚至有几种形式的错误处理(忽略错误,输出错误,抛出错误)。
注意:命名占位符功能使用反射和/或字典查找,因此您可以将JSON反序列化为C#对象或嵌套Dictionaries
,并且它可以正常工作!
答案 1 :(得分:2)
您是否考虑过使用Javascript作为脚本语言?虽然启动成本很高,但Jint取得了巨大的成功。另一种选择是Jurassic,我自己没有用过。
如果你碰巧有一个Web应用程序,使用Razor可能是一个想法,see here。
使用Regex或任何类型的字符串解析当然可以解决琐碎的事情,但是当你想要逻辑甚至只是基本的层次结构时会很痛苦。如果将JSON反序列化为嵌套字典,则可以相对容易地构建解析器:
// Untested and error prone, just to illustrate the concept
var parts = "parentObj.childObj.property".split('.');
Dictionary<object,object> current = yourDeserializedObject;
foreach(var key in parts.Take(parts.Length-1)){
current = current[key];
}
var value = current[parts.Last()];
无论你做什么,都不要做XSLT。真的,如果XSLT是答案那么问题肯定是非常绝望的:)
答案 2 :(得分:2)
我将如何做到这一点:
将模板更改为此格式Hi {Name.First}
现在创建一个JavaScriptSerializer
来转换Dictionary<string, object>
JavaScriptSerializer jss = new JavaScriptSerializer();
dynamic d = jss.Deserialize(data, typeof(object));
现在,变量d
在字典中包含JSON的值。
有了这个,您可以针对正则表达式运行模板,以递归方式将{X.Y.Z.N}
替换为字典的键。
完整示例:
public void Test()
{
// Your template is simpler
string template = "Hi {Name.First}";
// some JSON
string data = @"{""Name"":{""First"":""Jack"",""Last"":""Smith""}}";
JavaScriptSerializer jss = new JavaScriptSerializer();
// now `d` contains all the values you need, in a dictionary
dynamic d = jss.Deserialize(data, typeof(object));
// running your template against a regex to
// extract the tokens that need to be replaced
var result = Regex.Replace(template, @"{?{([^}]+)}?}", (m) =>
{
// Skip escape values (ex: {{escaped value}} )
if (m.Value.StartsWith("{{"))
return m.Value;
// split the token by `.` to run against the dictionary
var pieces = m.Groups[1].Value.Split('.');
dynamic value = d;
// go after all the pieces, recursively going inside
// ex: "Name.First"
// Step 1 (value = value["Name"])
// value = new Dictionary<string, object>
// {
// { "First": "Jack" }, { "Last": "Smith" }
// };
// Step 2 (value = value["First"])
// value = "Jack"
foreach (var piece in pieces)
{
value = value[piece]; // go inside each time
}
return value;
});
}
我没有处理异常(例如找不到该值),您可以处理这种情况并返回匹配的值(如果找不到)。原始值为m.Value
,m.Groups[1].Value
之间的字符串为{}
。
答案 3 :(得分:1)
为什么不是我们nvelocity或其他什么?