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);
}
}
}
}
}