如何使用 Complex JSON 和 FTL 进行迭代

How To Iterate with Complex JSON and FTL

我有一个JSON,我应该在此基础上准备一个HTML。请在

下面找到我的 JSON
{
    "apiName": "myapi-v10",
    "eventKey": "monitor_records",
    "emailSubject": "local: PLAYER Records",
    "customFields": {
        "x_transaction_id": "9f99a9b0-30f5-11ea-8347-381c20524153",
        "emailData": {
            "Table 1": {
                "title": "Some X",
                "headers": [
                    "COUNT",
                    "PLAYER",
                    "STATUS"
                ],
                "data": [
                    {
                        "COUNT": 4,
                        "PLAYER": "APLAYER",
                        "STATUS": "Open"
                    },
                    {
                        "COUNT": 2,
                        "PLAYER": "APLAYER",
                        "STATUS": "Waiting"
                    },
                    {
                        "COUNT": 3,
                        "PLAYER": "CPLAYER",
                        "STATUS": "Closed"
                    },
                    {
                        "COUNT": 2,
                        "PLAYER": "CPLAYER,
                        "STATUS": "withheld"
                    },
                    {
                        "COUNT": 3,
                        "PLAYER": "NPLAYER",
                        "STATUS": "Closed"
                    },
                    {
                        "COUNT": 2,
                        "PLAYER": "NPLAYER",
                        "STATUS": "provationsiu"
                    },
                    {
                        "COUNT": 4,
                        "PLAYER": "WPLAYER",
                        "STATUS": "boost"
                    },
                    {
                        "COUNT": 1,
                        "PLAYER": "WPLAYER",
                        "STATUS": "No Status"
                    }
                ]
            },
            "Table 2": {
                "Title": "Some Y",
                "Headers": [
                    "COUNT",
                    "PLAYER",
                    "STATUS"
                ],
                "data": [
                    {
                        "COUNT": 4,
                        "PLAYER": "APLAYER",
                        "STATUS": "Open"
                    },
                    {
                        "COUNT": 2,
                        "PLAYER": "APLAYER",
                        "STATUS": "Closed"
                    },
                    {
                        "COUNT": 3,
                        "PLAYER": "CMH",
                        "STATUS": "Closed"
                    },
                    {
                        "COUNT": 2,
                        "PLAYER": "CMH",
                        "STATUS": "withheld"
                    },
                    {
                        "COUNT": 3,
                        "PLAYER": "NPLAYER",
                        "STATUS": "Closed"
                    },
                    {
                        "COUNT": 4,
                        "PLAYER": "WPLAYER",
                        "STATUS": "boost"
                    },
                    {
                        "COUNT": 1,
                        "PLAYER": "WPLAYER",
                        "STATUS": "No Status"
                    }
                ]
            }
        }
    }
}

我需要遍历 customFields->emailData 表并访问其中的每个值。我尝试了多种方法,但 none 似乎可行并抛出以下异常。

For "." left-hand operand: Expected a hash, but this has evaluated to a method+sequence

FTL 代码片段如下使用

<div style="font-family: Arial, Helvetica, sas-serif; font-size: 10pt;">
    <#assign tableValues = customFields.emailData?values>
    <#assign tableKeys = customFields.emailData?keys/>
    <#list tableKeys as tableKey>
        <#assign seq_index = tableKeys?seq_index_of(tableKey) />
        <#assign tableValue = tableValues[seq_index]/>
        <table class="demo">
            <caption>${tableValue.title}</caption>
            <thead>
                <tr>
                    <#list tableValue.headers as header>
                        <th>${header}</th>
                    </#list>
                </tr>
            </thead>
            <tbody>
                <#assign rows = table.data>
                <#list rows as row>
                    <tr>
                        <#list tableValue.headers as header>
                            <td>${row[header]}</td>
                        </#list>
                    </tr>
                </#list>
          </tbody>
        </table>
        <p>&nbsp;</p>
    </#list>
</div>            

注意:我使用的是 2.3.23 freemarker 版本,无法升级或降级到其他版本,因为这需要大量批准。

也欢迎任何修改 JSON 的建议,这将使 ftl 代码更简单。

尝试解析标题本身时失败。

异常跟踪:

Jan 08, 2020 11:05:32 AM freemarker.log._JULLoggerFactory$JULLogger error
SEVERE: Error executing FreeMarker template
FreeMarker template error:
For "." left-hand operand: Expected a hash, but this has evaluated to a method+sequence (wrapper: f.e.b.SimpleMethodModel):
==> tableValue  [in template "monitorapi-success.template" at line 30, column 52]

----
Tip: Maybe using obj.something(params) instead of obj.something will yield the desired value
----

----
FTL stack trace ("~" means nesting-related):
    - Failed at: ${tableValue.title}  [in template "monitorapi-success.template" at line 30, column 50]
----

Java stack trace (for programmers):
----
freemarker.core.NonHashException: [... Exception message was already printed; see it above ...]
    at freemarker.core.Dot._eval(Dot.java:45)
    at freemarker.core.Expression.eval(Expression.java:78)
    at freemarker.core.Expression.evalAndCoerceToString(Expression.java:82)
    at freemarker.core.DollarVariable.accept(DollarVariable.java:41)
    at freemarker.core.Environment.visit(Environment.java:324)
    at freemarker.core.MixedContent.accept(MixedContent.java:54)
    at freemarker.core.Environment.visitByHiddingParent(Environment.java:345)
    at freemarker.core.IteratorBlock$IterationContext.executeNestedBlockInner(IteratorBlock.java:240)
    at freemarker.core.IteratorBlock$IterationContext.executeNestedBlock(IteratorBlock.java:220)
    at freemarker.core.IteratorBlock$IterationContext.accept(IteratorBlock.java:194)
    at freemarker.core.Environment.visitIteratorBlock(Environment.java:572)
    at freemarker.core.IteratorBlock.acceptWithResult(IteratorBlock.java:78)
    at freemarker.core.IteratorBlock.accept(IteratorBlock.java:64)
    at freemarker.core.Environment.visit(Environment.java:324)
    at freemarker.core.MixedContent.accept(MixedContent.java:54)
    at freemarker.core.Environment.visit(Environment.java:324)
    at freemarker.core.Environment.process(Environment.java:302)
    at freemarker.template.Template.process(Template.java:325)
    at TestEmailTemplate.main(TestEmailTemplate.java:24)

Exception in thread "main" FreeMarker template error:
For "." left-hand operand: Expected a hash, but this has evaluated to a method+sequence (wrapper: f.e.b.SimpleMethodModel):
==> tableValue  [in template "monitorapi-success.template" at line 30, column 52]

----
Tip: Maybe using obj.something(params) instead of obj.something will yield the desired value
----

----
FTL stack trace ("~" means nesting-related):
    - Failed at: ${tableValue.title}  [in template "monitorapi-success.template" at line 30, column 50]
----

Java stack trace (for programmers):
----
freemarker.core.NonHashException: [... Exception message was already printed; see it above ...]
    at freemarker.core.Dot._eval(Dot.java:45)
    at freemarker.core.Expression.eval(Expression.java:78)
    at freemarker.core.Expression.evalAndCoerceToString(Expression.java:82)
    at freemarker.core.DollarVariable.accept(DollarVariable.java:41)
    at freemarker.core.Environment.visit(Environment.java:324)
    at freemarker.core.MixedContent.accept(MixedContent.java:54)
    at freemarker.core.Environment.visitByHiddingParent(Environment.java:345)
    at freemarker.core.IteratorBlock$IterationContext.executeNestedBlockInner(IteratorBlock.java:240)
    at freemarker.core.IteratorBlock$IterationContext.executeNestedBlock(IteratorBlock.java:220)
    at freemarker.core.IteratorBlock$IterationContext.accept(IteratorBlock.java:194)
    at freemarker.core.Environment.visitIteratorBlock(Environment.java:572)
    at freemarker.core.IteratorBlock.acceptWithResult(IteratorBlock.java:78)
    at freemarker.core.IteratorBlock.accept(IteratorBlock.java:64)
    at freemarker.core.Environment.visit(Environment.java:324)
    at freemarker.core.MixedContent.accept(MixedContent.java:54)
    at freemarker.core.Environment.visit(Environment.java:324)
    at freemarker.core.Environment.process(Environment.java:302)
    at freemarker.template.Template.process(Template.java:325)
    at TestEmailTemplate.main(TestEmailTemplate.java:24)

Process finished with exit code 1

当我将 JSON 转换为 HashMap 时问题已解决。