2


我在我的项目中使用 JODReports (http://jodreports.sourceforge.net/) 来生成文档。问题在于 '[#if...]' 指令中的 'AND' 逻辑运算。示例(在“.odt”模板中):

[#if entry1?? AND entry2??]bla bla[/#if]

如果存在“entry1”和“entry2”并且它们不是空值,则应该写为“bla bla”,但是在解析模板时出现错误:

freemarker.core.ParseException: Encountered "AND" at line 4, column 30424 in content.xml.
Was expecting one of:
    ">" ...
    "." ...
    "[" ...
    "(" ...
    "?" ...
    "!" ...
    <TERMINATING_EXCLAM> ...
    "??" ...
    "+" ...
    "-" ...
    "*" ...
    "/" ...
    "%" ...
    "!=" ...
    "=" ...
    "==" ...
    ">=" ...
    <ESCAPED_GTE> ...
    ">" ...
    <ESCAPED_GT> ...
    <LESS_THAN_EQUALS> ...
    <LESS_THAN> ...
    ".." ...
    <AND> ...
    <OR> ...

    at freemarker.core.FMParser.generateParseException(FMParser.java:4697)
    at freemarker.core.FMParser.jj_consume_token(FMParser.java:4568)
    at freemarker.core.FMParser.If(FMParser.java:1171)
    at freemarker.core.FMParser.FreemarkerDirective(FMParser.java:2372)
    at freemarker.core.FMParser.Content(FMParser.java:2618)
    at freemarker.core.FMParser.OptionalBlock(FMParser.java:2786)
    at freemarker.core.FMParser.List(FMParser.java:1257)
    at freemarker.core.FMParser.FreemarkerDirective(FMParser.java:2375)
    at freemarker.core.FMParser.Content(FMParser.java:2618)
    at freemarker.core.FMParser.OptionalBlock(FMParser.java:2786)
    at freemarker.core.FMParser.Escape(FMParser.java:2302)
    at freemarker.core.FMParser.FreemarkerDirective(FMParser.java:2445)
    at freemarker.core.FMParser.Content(FMParser.java:2618)
    at freemarker.core.FMParser.OptionalBlock(FMParser.java:2786)
    at freemarker.core.FMParser.Root(FMParser.java:2958)
    at freemarker.template.Template.<init>(Template.java:149)
    at freemarker.template.Template.<init>(Template.java:172)...

这很奇怪,因为“AND”在预期语句列表中。更改模板为:

    [#if (entry1??) AND (entry2??)]bla bla[/#if]
    [#if entry1?? <AND> entry2??]bla bla[/#if]
    [#if (entry1??) <AND> (entry2??)]bla bla[/#if]
    [#if (entry1)?? AND (entry2)??]bla bla[/#if]
    [#if entry1?? [AND] entry2??]bla bla[/#if]
    [#if (entry1??) [AND] (entry2??)]bla bla[/#if]

也不起作用。使用 '&&' 或 '&' 而不是 'AND' 会给我错误:

freemarker.core.ParseException: Encountered ";" at line 4, column 30430 in content.xml.
Was expecting one of:
    ">" ...
    "." ...
    "[" ...
    "(" ...
    "?" ...
    "!" ...
    <TERMINATING_EXCLAM> ...
    "??" ...
    "+" ...
    "-" ...
    "*" ...
    "/" ...
    "%" ...
    "!=" ...
    "=" ...
    "==" ...
    ">=" ...
    <ESCAPED_GTE> ...
    ">" ...
    <ESCAPED_GT> ...
    <LESS_THAN_EQUALS> ...
    <LESS_THAN> ...
    ".." ...
    <AND> ...
    <OR> ...

    at freemarker.core.FMParser.generateParseException(FMParser.java:4697)
    at freemarker.core.FMParser.jj_consume_token(FMParser.java:4568)
    at freemarker.core.FMParser.If(FMParser.java:1171)
    at freemarker.core.FMParser.FreemarkerDirective(FMParser.java:2372)
    at freemarker.core.FMParser.Content(FMParser.java:2618)
    at freemarker.core.FMParser.OptionalBlock(FMParser.java:2786)
    at freemarker.core.FMParser.List(FMParser.java:1257)
    at freemarker.core.FMParser.FreemarkerDirective(FMParser.java:2375)
    at freemarker.core.FMParser.Content(FMParser.java:2618)
    at freemarker.core.FMParser.OptionalBlock(FMParser.java:2786)
    at freemarker.core.FMParser.Escape(FMParser.java:2302)...

我当然可以写两个“[#if]”指令——像这样:[#if entry1??][#if entry2??]bla bla[/#if][/#if]——但我不想那样做。有什么建议么?
谢谢, 阿雷克

4

2 回答 2

3

FreeMarker 没有类似andor的运算符AND,它只有&&. 所以[#if entry1?? && entry2??]bla bla[/#if]应该工作。从您在这种情况下收到的错误消息中,我假设某些东西(不是 FreeMarker)已经逃脱了&&to &amp;&amp;。需要防止这种情况,然后它将起作用。

在错误消息中说明AND支持,这是一个原始的 JavaCC 错误消息,它只是说标识为<AND>受支持的令牌......我建议在有疑问时使用 FreeMarker 的文档:http: //freemarker.org/docs/ dgui_template_exp.html#dgui_template_exp_logicalop

于 2012-08-23T07:59:39.663 回答
1

如果您查看 JODReport JUnit 测试

公共无效 testDirectiveWithSpecialChars() :

https://github.com/hernad/jodreports/blob/master/jodreports/src/test/java/net/sf/jooreports/templates/TextInputTagTest.java

使用此 ODT:

https://github.com/hernad/jodreports/blob/master/jodreports/src/test/resources/textinput-directives-special-chars-template.odt

情况相同,此测试正确通过。

        <text:p text:style-name="Standard">
            <text:text-input text:description="jooscript">[#if (cond1==&apos;pass&apos; &amp;&amp; cond2==&apos;pass&apos;)]</text:text-input>
        </text:p>
        <text:p text:style-name="Standard">All passed!</text:p>
        <text:p text:style-name="Standard">
            <text:text-input text:description="jooscript">[#elseif (cond1==&apos;pass&apos; || cond2==&apos;pass&apos;)]</text:text-input>
        </text:p>
        <text:p text:style-name="Standard">Partly passed!</text:p>
        <text:p text:style-name="Standard">
            <text:text-input text:description="jooscript">[#else]</text:text-input>
        </text:p>
        <text:p text:style-name="Standard">All failed!</text:p>
        <text:p text:style-name="Standard">
            <text:text-input text:description="jooscript">[/#if]</text:text-input>
        </text:p>

但是当你删除标签时:

<text:text-input text:description="jooscript"> </text:text-input>

正如您所描述的,测试将失败。所以现在,解决方案是使用该标签来封装您的代码。

马丁

于 2015-03-30T11:50:29.900 回答