2014-04-24 20 views
0

我正在编写一个需要使用HTML文件作为模板的报告系统。我正在寻找使用Nustache来处理这个问题,因为它看起来很理想,非常轻便。我遇到的唯一问题是我需要能够在数字数据绑定项中指定特定的小数位数。.NET模板引擎中的字符串格式(理想的是Nustache)

我知道我可以在数据源中有一个访问器属性,它在内部执行一个String.Format,然后返回一个表示数字的格式化字符串。问题在于模板本身无法指定格式(例如小数位数)。

有没有一种方法可以指定模板本身的小数位?因为我非常喜欢Nustache,所以我正在写一些处理格式化前后处理模板文件的内容。但是想要检查一下,如果这已经被支持,我不会重新发明轮子,而且我错过了一些现有的功能。

我在想如果在允许Nustache做它的事情之前,预处理将{{MyNumber|3}}替换为<$$${{MyNumber}}|3$$$>。其中3是小数位数。所以它会看起来像<$$$123|3$$$>。然后在Nustache进行处理之后,我会有一个后处理过程,使用正则表达式提取Nustache插入的数字和3,然后执行字符串格式并进行替换。请注意,<$$$$$$>只是由字符串组成,以指示后处理需要处理的块的开始和结束。

在我的情况下,我只需要这个来指定小数位,所以我可以安全地推测其中{{x | y}}的任何内容都是十进制值,其中y表示小数位。

我正在重塑一个车轮吗?任何其他想法?或者这个解决方案的问题?

+3

你的问题是无题的StackOverflow。为什么不使用[T4](http://msdn.microsoft.com/zh-cn/library/bb126445.aspx)? –

+0

为什么它是题外话?阅读帮助中心文章,它对我来说是主题。感谢T4的建议 - 我会做一些阅读。我以前听过这个名字,但还不知道。 – Dan

+1

*要求我们推荐或找到工具,图书馆或最喜欢的非现场资源的问题是堆栈溢出的主题,因为它们倾向于吸引自以为是的答案和垃圾邮件。相反,请描述问题以及到目前为止解决问题所做的工作。*我没有制定SO规则,我很抱歉,虽然 –

回答

0

我实际上实施了我的建议,因为它不需要很长时间就可以做到。似乎很好地工作。这是有限的,因为它假设{{x|y}}与x作为十进制类型和y作为十进制字符数。我还用<######>来代替,因为$用于正则表达式替换字符串(例如$ 1是第一个匹配的组等)。所以使用#意味着我不必逃避它们。

只是柜面任何人的兴趣,下面的代码:

using System.Text.RegularExpressions; 

public static class NustacheUtil 
{ 
    public static string PreProcess(string templateString) 
    { 
     return Regex.Replace(templateString, @"{{(.*?)\|(\d+)}}", @"<###{{$1}}|$2###>"); 
    } 

    public static string PostProcess(string templateString) 
    { 
     var result = templateString; 

     for(;;) 
     { 
      var match = Regex.Match(result, @"<###([0-9.]+?)\|(\d+)###>"); 

      if(!match.Success || match.Groups.Count != 3) 
      { 
       break; 
      } 

      decimal value; 

      if(decimal.TryParse(match.Groups[1].Value, out value)) 
      { 
       var numDecimalPlaces = match.Groups[2].Value; 
       result = result.Remove(match.Index, match.Length); 
       result = result.Insert(match.Index, value.ToString("N" + numDecimalPlaces)); 
      } 
     } 

     return result; 
    } 
} 

和几个测试:

using NUnit.Framework; 

[TestFixture] 
class NustacheUtilTests 
{ 
    [Test] 
    public void PreProcessTest_Single() 
    { 
     // Arrange 
     const string templateString = "Test number: {{MyNumber|3}}"; 

     // Act 
     var result = NustacheUtil.PreProcess(templateString); 

     // Assert 
     Assert.That(result, Is.EqualTo("Test number: <###{{MyNumber}}|3###>")); 
    } 

    [Test] 
    public void PostProcessTest_Single() 
    { 
     // Arrange 
     const string templateString = "Test number: <###123.456789|3###>"; 

     // Act 
     var result = NustacheUtil.PostProcess(templateString); 

     // Assert 
     Assert.That(result, Is.EqualTo("Test number: 123.457")); 
    } 

    [Test] 
    public void PreProcessTest_Multiple() 
    { 
     // Arrange 
     const string templateString = "Test number: {{MyNumber|3}}, and another: {{OtherNumber|2}}"; 

     // Act 
     var result = NustacheUtil.PreProcess(templateString); 

     // Assert 
     Assert.That(result, Is.EqualTo("Test number: <###{{MyNumber}}|3###>, and another: <###{{OtherNumber}}|2###>")); 
    } 

    [Test] 
    public void PostProcessTest_Multiple() 
    { 
     // Arrange 
     const string templateString = "Test number: <###123.457|3###>, and another: <###947.74933|2###>"; 

     // Act 
     var result = NustacheUtil.PostProcess(templateString); 

     // Assert 
     Assert.That(result, Is.EqualTo("Test number: 123.457, and another: 947.75")); 
    } 
} 

和用法与Nustache:

var templateString = NustacheUtil.PreProcess(templateString); 
templateString = Render.StringToString(templateString, dataSource); 
templateString = NustacheUtil.PostProcess(templateString); 

它显然还没有被用于愤怒。当我进行更改时,我会在这里更新代码,因为我相信我会在正确使用它时进行改进。

相关问题