使用Castle NVelocity我遇到了一个奇怪的问题...
如果模板字符串以$字符结尾,则会抛出以下异常:
词法错误:NVelocity.Runtime.Parser.TokenMgrError:词法错误 在第1行,第94栏。遇到:之后:“”
如果我在字符串的末尾添加一个空格或任何其他字符,它将按预期工作。
有人有解决方法吗?
以下是一些重现问题的示例代码:
class Program
{
static void Main(string[] args)
{
var result = Merge("The quick brown ${Animal} jumps over the lazy dog$", new List<KeyValuePair<string, string>>() { new KeyValuePair<string, string>("Animal", "fox") });
Console.WriteLine("Success: {0}", result.Key);
Console.WriteLine("Message: {0}", result.Value);
Console.Read();
}
public static KeyValuePair<bool, string> Merge(string template, IList<KeyValuePair<string, string>> data)
{
var ret = new KeyValuePair<bool, string>(false, null);
try
{
if (data != null)
{
var engine = new VelocityEngine();
engine.Init();
var context = new VelocityContext();
foreach (var tokenData in data)
{
context.Put(tokenData.Key, tokenData.Value);
}
var templateContent = template;
var sb = new StringBuilder();
var textWriter = new StringWriter(sb);
engine.Evaluate(context, textWriter, String.Empty, templateContent);
ret = new KeyValuePair<bool, string>(true, sb.ToString());
}
}
catch (Exception ex)
{
ret = new KeyValuePair<bool, string>(false, ex.Message);
}
return ret;
}
}
答案 0 :(得分:2)
您有几个选择:
如果您对要合并的输入字符串没有影响,请确保它们没有尾随的美元字符,至少不适用于合并过程:
示例:
bool dollarAtEnd = false;
if (input.EndsWith('$'))
{
input += " ";
dollarAtEnd = true;
}
var result = Merge(input, ...);
if (dollarAtEnd)
{
result = result.Substring(1, result.Length - 1);
}
如果您可以控制输入字符串,但只要求其中一些字符串以美元字符结尾,则可以执行以下操作:
示例:
"#set($dollar='$')The quick brown ${Animal} jumps over the lazy dog$dollar"
或者将“dollar”作为变量传递给VelocityContext,而不是将其指定为内联。
答案 1 :(得分:0)
$
表示变量名称的开头,如果要使用$ literal,则需要将其转义为\$
。
http://velocity.apache.org/engine/devel/user-guide.html#Getting_literal