我在C#控制檯應用程序中使用Razor模板引擎,並嘗試將對象樹展開爲文本文件。我在理解如何讓分層擴展工作方面遇到一些困難。如何實現分層剃刀模板擴展?
很可能我完全誤解了分層模板擴展應該如何在Razor中工作。我需要知道,如果我目前的方法幾乎是正確的,只需要修復,或者如果我完全以錯誤的方式完成,那麼做到這一點的正確方法是什麼?
獎勵問題:Razor是否是正確的工具或者是否有更好的選擇?
我已經創建了一個小測試應用程序來演示問題。類TemplateTreeModel
定義了傳入Razor的模型。這個類定義了一棵樹,Children
成員是一個兒童TemplateTreeModel
實例的列表。
我想實例的模型,並將其傳遞到剃刀這樣的:
var model = new TemplateTreeModel();
... add children to the tree ...
var expanded = Razor.Parse(Template, model);
TemplateTreeModel
有一個成員函數ExpandChildren
,做層次擴展。我在這樣的模板中使用它:
@(Model.ExpandChildren())
我的測試應用程序生成非常奇怪的結果。一些葉子節點在輸出中重複出現,只有3級節點存在。輸出中缺少根節點(級別1)和級別2節點。
更新:對於這一點的更多上下文,真正的用例是我想從抽象語法樹生成代碼。所以我有一堆代表每個AST節點輸出腳本的模板。然後,我想從根AST節點遞歸地擴展以將AST轉換爲腳本文件。
以下是測試應用程序的完整代碼。爲了得到這個工作,你需要把代碼放在一個C#控制檯應用程序和參考RazorEngine(可在這裏獲得http://razorengine.codeplex.com/)。
using System;
using System.Collections.Generic;
using System.Text;
using RazorEngine;
using RazorEngine.Templating;
namespace RazorTest
{
public class Program
{
public class TemplateTreeModel
{
private static int nextID = 1;
public TemplateTreeModel(string template, int level)
{
this.Level = level;
this.ID = nextID++;
this.Template = template;
this.Children = new List<TemplateTreeModel>();
}
public int Level { get; private set; }
public int ID { get; private set; }
public string Template { get; private set; }
public List<TemplateTreeModel> Children { get; private set; }
public string ExpandChildren()
{
var output = new StringBuilder();
foreach (var child in this.Children)
{
output.Append(child.Expand());
}
return output.ToString();
}
public string Expand()
{
var expanded = Razor.Parse(this.Template, this);
return expanded;
}
public TemplateTreeModel DefineChild(TemplateTreeModel child)
{
this.Children.Add(child);
return this;
}
}
public static void Main(string[] args)
{
try
{
var template = "Node: @Model.ID (Level @Model.Level):\[email protected](Model.ExpandChildren())\n";
var root =
new TemplateTreeModel(template, 1).
DefineChild(
new TemplateTreeModel(template, 2).
DefineChild(
new TemplateTreeModel(template, 3)
).DefineChild(
new TemplateTreeModel(template, 3)
)
).DefineChild(
new TemplateTreeModel(template, 2).
DefineChild(
new TemplateTreeModel(template, 3)
).DefineChild(
new TemplateTreeModel(template, 3)
)
);
var expanded = root.Expand();
Console.WriteLine(expanded);
}
catch (TemplateCompilationException ex)
{
Console.WriteLine("Template compilation errors:");
foreach (var error in ex.Errors)
{
Console.WriteLine(error);
}
}
}
}
}