我在 C# 控制台应用程序中使用 Razor 模板引擎并尝试将对象树扩展为文本文件。我在弄清楚如何使分层扩展起作用时遇到了一些困难。
很可能我完全误解了分层模板扩展应该如何在 Razor 中工作。我需要知道我目前的方法是否几乎是正确的并且只需要修复,或者我是否以完全错误的方式进行操作,那么正确的方法是什么?
额外的问题:Razor 是解决此问题的正确工具还是有更好的选择?
我创建了一个小型测试应用程序来演示该问题。该类TemplateTreeModel
定义传递给 Razor 的模型。这个类定义了一棵树,Children
成员是子TemplateTreeModel
实例的列表。
我想实例化模型并将其传递给 Razor,如下所示:
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):\n@(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);
}
}
}
}
}