代码之家  ›  专栏  ›  技术社区  ›  MitchBroadhead

订单列表项目标签罗马数字

  •  1
  • MitchBroadhead  · 技术社区  · 7 年前

    我正在将两个XSLT文件转换为FreeMarker。一个是HTML,另一个是FO。我需要能够基于变量生成列表项标签 定型的 它可以是值1、a、a、i、i(在HTML排序列表类型中使用)之一。

    原始html.xsl

    <ol type="{typeordered}">
        <li>...</li>
    </ol>
    

    原始文件

    <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>
                    &#x2022;
                </#if>
            </fo:block>
        </fo:list-item-label>
        ...
    </fo:list-item>
    
    2 回复  |  直到 7 年前
        1
  •  1
  •   gil.fernandes    7 年前

    喜欢 ddekany 提到你可以创建你自己的方法。下面是一个如何做到这一点的示例:

    Java代码

    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));
    

    这就是你在 模板引擎 :

    ${roman(true, 1234)}
    
        2
  •  2
  •   ddekany    7 年前

    在2.3.28中,没有FreeMarker的罗马格式格式化(也没有Java,上次我检查过了)。可能应该有…但现在,你必须自己滚(写一个 TemplateMethodModelEx 为它)。

    推荐文章