Velocity Context 中的 Velocity 模板转义 XML

Velocity template escape XML from Velocity Context

我有一个 velocity 模板,它代表一个 XML 文件。我使用传递给 VelocityContext 对象的数据填充标签之间的文本。然后在模板中访问它。

这是一个例子,我们称之为 myTemplate.vm:

<text>$myDocument.text</text>

这就是我将该数据传递给速度文件并将其构建为字符串输出的方式:

private String buildXml(Document pIncomingXml)
  {
    // setup environment
    Properties lProperties = new Properties();
    lProperties.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");

    VelocityContext lVelocityContext = new VelocityContext();
    lVelocityContext.put("myDocument" , pIncomingXml.getRootElement());

    StringWriter lOutput = new StringWriter();

    try
    {
      Velocity.init(lProperties);
      Velocity.mergeTemplate("myTemplate.vm", "ISO-8859-1", lVelocityContext, lOutput);
    }
    catch (Exception lEx)
    {
      throw new RuntimeException("Problems running velocity template, underlying error is " + lEx.getMessage(), lEx);
    }
    return lOutput.toString();
}

问题是,当我在模板文件中访问 myDocument.text 时,它会输出未转义为 XML 的文本。

我通过为转义工具添加 VelocityContext 找到了解决此问题的方法,如下所示:

lVelocityContext.put("esc", new EscapeTool());

然后使用它在模板中包装我的标签:

<text>$esc.xml($myDocument.text)</text>

实际情况是我有一个非常大的模板,手动将每个元素包装在 $esc.xml 上下文中将非常耗时。有没有一种方法可以让我在访问 myDocument 时告诉 XML velocity 在根本不编辑模板文件的情况下逃逸?

是的,有可能。

你需要做的是使用EscapeXMLReference, which implements the reference insertion handler接口:

lProperties.put("eventhandler.referenceinsertion.class",
                 "org.apache.velocity.app.event.implement.EscapeXmlReference");