私は単純なクラスを書きました。それはないすべては、@nameは、あなたが@adjective今日見こんにちはこの単純なテンプレートレンダリングクラスを改善するにはどうすればよいですか?
のような入力の文字列を取ります!
そして、@variables
は辞書の値に置き換えられます。たとえば、new Dictionary<string,object>{{"name","Ralph"},{"adjective","stunning"}}
を渡すと、次のようになります。
こんにちはラルフ、あなたは今日見事に見えます!
ここでは、クラスの:
class Template
{
List<object> nodes = new List<object>();
public Template(string content)
{
for (int i = 0; i < content.Length; ++i)
{
char ch = content[i];
if (ch == '@')
{
var match = Regex.Match(content.Substring(i + 1), @"\w+");
if (match.Success)
{
nodes.Add(new Variable(match.Value));
i += match.Value.Length;
}
else
{
throw new Exception(string.Format("Expected variable name after @ symbol at character {0}", i));
}
}
else
{
nodes.Add(ch.ToString());
}
}
}
public string Render(Dictionary<string,object> dict)
{
var sb = new StringBuilder();
foreach (var item in nodes)
{
if (item is Variable)
{
sb.Append(dict[((Variable)item).Name]);
}
else
{
sb.Append(item);
}
}
return sb.ToString();
}
class Variable
{
public readonly string Name;
public Variable(string name)
{
Name = name;
}
}
}
は、このような問題への良いアプローチですか?私はできるだけ多くの処理をコンストラクタでやりたいので、テンプレートを再解析することなく効率的にテンプレートを何度も再レンダリングすることができます。
今、私は変数ノードを探してノードリスト全体をループしていますので、それらを置き換えることができます。おそらく、それらのノードに「スキップ」できる方法がありますか?助けてくれますか?
また、文字ごとに解析していますが、正規表現(次の文字から開始したいので、残りの文字列を取得するために.Substringを使用しています)を使用して、 "チャンク"私はどのように私は/正規表現を使用して外に全体の変数名を得るかもしれないか分からないのですか?
このクラスはかなり複雑になりつつあります。そのため、私はさらに進める前に正しいアプローチを取っていますか?
私の2の懸念は、以下のとおりです。
- カウンタを現在の位置からテキストのチャンクを引き出し、そして進めるための良い方法は何ですか?たとえば、変数名を抽出すると、次のテキストが実際には変数名になるはずです。
- すぐにテンプレートを何度も何度もレンダリングできるように、ノード(この場合はテキストノードと変数ノードのみ)を保存する方法はありますか?
s = s.Replace("@name", name); s = s.Replace("@Adjective", adjective);
また、私はテキストを解析するときに例外をスロー避けるだろう:についてどう
テンプレートでレンダリングしようとするのは、テキストだけですか? RegExesは分岐構造には適していません。 – pbalaga
@rook:はい、 "text"とは "文字列"を意味しますが、将来はJSONやXMLなどのHTMLになります。明確にするために、*出力*は入力ではなくHTMLです。 – mpen