我正在将两个XSLT文件转换为freemarker。一个是HTML,另一个是FO。我需要能够基于变量 typeordered 生成列表项标签,该变量可以是值1,a,A,i,I(用于html有序列表类型)。>
原始html.xsl
<ol type="{typeordered}">
<li>...</li>
</ol>
原始fo.xsl
<fo:list-item>
<fo:list-item-label end-indent="label-end()">
<fo:block><xsl:number format="{typeordered}" /></fo:block>
</fo:list-item-label>
...
</fo:list-item>
FO freemarker版本。可以做小写/大写字母,但是怎么做罗马数字?似乎太复杂了?
<#macro listItemM listItem listElement n>
<fo:list-item>
<fo:list-item-label end-indent="label-end()">
<fo:block>
<#if listElement.type == "ordered">
<#if listElement.typeordered??>
<#if listElement.typeordered == "a">
${n?lower_abc}
<#elseif listElement.typeordered == "A">
${n?upper_abc}
<#else>
${n}
</#if>
<#else>
${n}
</#if>.
<#else>
•
</#if>
</fo:block>
</fo:list-item-label>
...
</fo:list-item>
答案 0 :(得分:2)
从2.3.28开始,FreeMarker中没有内置罗马数字格式(上次我没有检查过Java)。也许应该有……但是,现在,您必须自己动手(为其写一个TemplateMethodModelEx
)。
答案 1 :(得分:1)
像ddekany所述,您可以创建自己的方法。这是如何执行此操作的示例:
import freemarker.template.*;
import java.util.List;
import java.util.TreeMap;
public class RomanNumerals implements TemplateMethodModelEx {
private final static TreeMap<Integer, String> map = new TreeMap<>();
static {
map.put(1000, "M");
map.put(900, "CM");
map.put(500, "D");
map.put(400, "CD");
map.put(100, "C");
map.put(90, "XC");
map.put(50, "L");
map.put(40, "XL");
map.put(10, "X");
map.put(9, "IX");
map.put(5, "V");
map.put(4, "IV");
map.put(1, "I");
}
// Copied from Stackoverflow https://stackoverflow.com/a/19759564/2735286
private static String toRoman(int number) {
int l = map.floorKey(number);
if (number == l) {
return map.get(number);
}
return map.get(l) + toRoman(number - l);
}
@Override
public Object exec(List arguments) throws TemplateModelException {
final boolean upperCase = ((TemplateBooleanModel) arguments.get(0)).getAsBoolean();
final Integer number = ((SimpleNumber) arguments.get(1)).getAsNumber().intValue();
String roman = toRoman(number);
return new SimpleScalar(upperCase ? roman : roman.toLowerCase());
}
}
在处理模板之前,您必须将其插入数据模型图中:
HashMap<String, Object> dataModel = new HashMap<>();
dataModel.put("date", new Date());
dataModel.put("roman", new RomanNumerals());
testTemplate.process(dataModel, new PrintWriter(System.out));
这是在 Freemarker 中使用它的方式:
${roman(true, 1234)}