Получение списка заполнителей из шаблона Velocity

предположим, у меня есть шаблон Velocity, подобный этому:

Hi!, my name is ${name} and I'm ${age} years old.

Обратите внимание, что в шаблоне нет циклов или условных операторов.

Я хотел бы получить список с этими значениями

["name", "age"]

Я проверил API, но похоже, что класс Template не имеет для этого метода: https://velocity.apache.org/engine/releases/velocity-1.7/apidocs/org/apache/velocity/Template.html

Как я могу получить этот список с использованием скорости без разбора шаблона самостоятельно?


person ordago    schedule 30.04.2013    source источник
comment
Я сделал это, но на данный момент у меня нет источника. Я думаю, что в конечном итоге я использовал посетителей, но не могу вспомнить подробности.   -  person Dave Newton    schedule 30.04.2013
comment
Вы можете реализовать свой собственный Context, который добавляет ключи вызовов containsKey или get к Set<String> и использовать их вместе с NullWriter (commons-io) на этапе предварительной обработки. Помимо того, что это как-то нехорошо, это также страдает от теоретического недостатка, что никто гарантирует (хотя это должно работать, я думаю), что Velocity вызовет любой из двух методов, потому что он не находит никаких ключей появляется в getKeys().   -  person misberner    schedule 30.04.2013


Ответы (1)


Я также искал способ получить список всех ключей, используемых в шаблоне Velocity. Как упоминалось в одном из комментариев, вы можете реализовать свой собственный посетитель для прохождения через все узлы в шаблоне Velocity.

Вот фрагмент, который хранит ключи, встречающиеся в шаблоне, и затем распечатывает их:

VelocityEngine ve = new VelocityEngine();
Properties props = new Properties();
props.put("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
props.put("resource.loader", "class");
ve.init(props);
Template t = ve.getTemplate("templates/my-template.vm");

final List<String> keys = new ArrayList<String>();
SimpleNode sn = (SimpleNode)t.getData();
BaseVisitor myVisitor = new BaseVisitor(){
    @Override
    public Object visit(ASTReference node, Object data){
        String key = node.literal();
        keys.add(key);
        return super.visit(node, data);
    }
};
sn.jjtAccept(myVisitor, new Object());
for (String key : keys) {
    System.out.println(key);
}

Например, если ваш шаблон Velocity имеет следующее содержимое:

<p>Dear ${user.name}, the ordered package has been sent to ${user.address}.</p>

Будет напечатано следующее:

${user.name}
${user.address}
person Yannick De Turck    schedule 16.12.2014