繁体   English   中英

我应该采用哪种C#模板方法?

[英]Which approach to templating in C# should I take?

我拥有的是存储在数据库中的模板,以及在C#中转换为字典的JSON数据。

例:

模板:“嗨{FirstName}”

数据:“{FirstName:'Jack'}”

通过使用正则表达式提取模板中{}内的任何内容,这可以轻松处理一个级别的数据。

我想要的是我希望能够比第一层更深入地了解JSON。

例:

模板:“嗨{姓名:{First}}”

数据:“{姓名:{第一名:'杰克',最后一名:'史密斯'}}”

我应该采取什么方法? (以及从哪个选择开始的一些指导)

  1. 正则表达式
  2. 不在模板中使用JSON(支持xslt或类似的东西)
  3. 还有别的

我也希望能够遍历模板中的数据,但我根本不知道从哪一个开始!

谢谢堆

你很幸运! 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 "

您可以查看命名占位符列表格式化程序的单元测试, 查看更多示例!

它甚至有几种形式的错误处理(忽略错误,输出错误,抛出错误)。

注意: 命名的占位符功能使用反射和/或字典查找,因此您可以将JSON反序列化为C#对象或嵌套Dictionaries ,它将工作得很好!

您是否考虑过使用Javascript作为脚本语言? 虽然启动成本很高,但我在Jint取得了巨大的成功。 另一种选择是侏罗纪 ,我没有用过。

如果您碰巧有一个Web应用程序,使用Razor可能是一个想法, 请参阅此处

使用正则表达式或任何类型的字符串解析肯定可以用于琐碎的事情,但是当你想要逻辑甚至只是基本的层次结构时会变得很痛苦。 如果将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是答案那么问题一定是非常绝望的:)

我将如何做到这一点:

将模板更改为此格式Hi {Name.First}

现在创建一个JavaScriptSerializer来转换Dictionary<string, object> JSON

JavaScriptSerializer jss = new JavaScriptSerializer();
dynamic d = jss.Deserialize(data, typeof(object));

现在变量d在字典中具有JSON的值。

有了这个,您可以针对正则表达式运行模板,以递归方式将{XYZN}替换为字典的键。

完整示例:

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{}之间的字符串值。

为什么不是我们的nvelocity还是什么?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM