2011-11-06 81 views
6

我有什麼 我有存儲在數據庫中的模板以及在C#中轉換爲字典的JSON數據。我應該採用哪種方法在C#中進行模板化?

實施例:

模板: 「{FirstName}您好」

數據: 「{姓: '傑克'}」

這通過使用正則表達式的數據中的一個電平的工作原理很容易地抽出模板中{}內的任何內容。

我想要什麼 我希望能夠比第一層更深入JSON。

例子:

模板: 「您好,{名稱:{一}}」

數據: 「{名稱:{第一: '傑克',最後: '史密斯'}}」

我應該採取什麼方法? (以及在哪裏與你的選擇,開始了一些指導)

  1. 正則表達式
  2. 模板中未使用JSON(支持XSLT或類似的東西)
  3. 別的東西

我也希望能夠循環訪問模板中的數據,但我不知道從哪一個開始。

謝謝你堆

回答

2

這裏是我會怎麼做:你的模板

更改爲這種格式Hi {Name.First}

現在創建一個JavaScriptSerializer轉換JSON在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{}之間的字符串。

2

你有沒有想過使用Javascript作爲你的腳本語言?我的Jint獲得了巨大成功,但啓動成本很高。另一種選擇是Jurassic,我沒有用過自己。

如果你碰巧有一個Web應用程序,使用Razor可能是一個想法,see here

使用正則表達式或任何類型的字符串解析當然可以用於微不足道的事情,但是當您需要邏輯甚至基本的層次結構時可能會變得很痛苦。如果反序列化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就是答案那麼問題一定是真的絕望了:)

+0

這聽起來像是XSLT的完美場景。 –

+0

只有當你喜歡它帶來的冗長。 –

+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 PlaceholdersList Formatter單元測試,看看還有更多的例子!

它甚至有幾種形式的錯誤處理(忽略錯誤,輸出錯誤,拋出錯誤)。

注:命名的佔位符功能使用反射和/或字典查找,這樣你就可以反序列化JSON到C#對象或嵌套Dictionaries,它會工作的偉大!

相關問題