Stringtemplate:是否可以将HashMap使用的模板应用于多值属性

发布于 2024-12-18 12:39:58 字数 1356 浏览 1 评论 0原文

我的 .stg 文件中有两个模板,它们都适用于 多值 HashMap。 HashMap 被用作注入对象。

我需要那些可以多次注入的 HashMap 实例。

我的麻烦是,当我切换到另一个模板时,ANTLR似乎 将第二个 HashMap 视为一个 List —— 多个对象和 null 价值。


Part of my .stg file shows as follows:

tpl_hash(BAR, FOO) ::= <<
<FOO:foo(); separator="\n">
<BAR:bar(); separator="\n">
>>

foo(nn) ::= <<
foo: <nn.name; null="NULL"> . <nn.national; null="NULL">
>>


bar(mm) ::= <<
bar: <mm.name> @ <mm.national>
>>

我的 .g 文件的一部分显示:

HashMap hm = new HashMap();
hm.put("name", $name.text);
hm.put("national", "German");
tpl_hash.add("FOO",new HashMap(hm));
HashMap hm2 = new HashMap();
hm2.put("name", $name.text);
hm2.put("national", "German");
tpl_hash.add("BAR",new HashMap(hm2));

我期望的结果是:

bar: Kant @ German
foo: Russell @ England

但是,我得到:

foo: NULL . NULL
foo: NULL . NULL
bar:  @ 
bar:  @ 

如果我们用 FOO 替换 BAR,则保持 FOO 和 BAR 相同 模板,输出是正确的,如下所示。

bar: Russell @ German
bar: Russell @ German

在文档中,“同步 ST 添加(字符串名称,对象值) org.stringtemplate.v4.ST”说:

“如果您发送一个列表,然后注入单个值元素,则 add() 复制原始列表并添加新值。”

HashMap 怎么样? StringTemplate 是否考虑 HashMap、键/值对 访问,一个有意的对象,作为列表和由注入的多值 错误?

There is two template in my .stg file, and both of them apply on
multi-value a HashMap. The HashMap is employed as an injected object.

And I need those instance of HashMap can be injected for many times.

My trouble is, when I switch to another template, ANTLR seems to
consider the second HashMap as a List -- multipul objects and null
value.


Part of my .stg file shows as follows:

tpl_hash(BAR, FOO) ::= <<
<FOO:foo(); separator="\n">
<BAR:bar(); separator="\n">
>>

foo(nn) ::= <<
foo: <nn.name; null="NULL"> . <nn.national; null="NULL">
>>


bar(mm) ::= <<
bar: <mm.name> @ <mm.national>
>>

Part of my .g file shows:

HashMap hm = new HashMap();
hm.put("name", $name.text);
hm.put("national", "German");
tpl_hash.add("FOO",new HashMap(hm));
HashMap hm2 = new HashMap();
hm2.put("name", $name.text);
hm2.put("national", "German");
tpl_hash.add("BAR",new HashMap(hm2));

The result I expect is :

bar: Kant @ German
foo: Russell @ England

But, I got:

foo: NULL . NULL
foo: NULL . NULL
bar:  @ 
bar:  @ 

If we replace BAR with FOO, as is, keeping FOO and BAR with identical
template, the output is right, like the following.

bar: Russell @ German
bar: Russell @ German

In docs, "synchronized ST add (String name, Object value) in
org.stringtemplate.v4.ST" said:

"If you send in a List and then inject a single value element, add()
copies original list and adds the new value."

What about a HashMap? Does StringTemplate consider the HashMap, key/value pair
access, an object purposely, as a List and as multi-value injected by
mistake?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

疾风者 2024-12-25 12:39:58

您的问题是您将 foo / bar 模板应用于地图中的每个项目而不是地图本身。

考虑以下数据结构:(

{
  "FOO": {
    "name": "Nick",
    "national":"German"
  },
  "BAR": {
    "name": "Karl",
    "national":"French"
  },
  "FIZZBUZZ": [
    {
      "name": "Kitty",
      "national":"English"
    },
    {
      "name": "Dan",
      "national":"Finnish"
    }
  ]
}

假设您已将 FOO 设置为结果映射、FIZZBUZZ 等)。

想象一下以下模板:

group blank;
main()::=<<
$foo(nn=FOO)$
$bar(mm=BAR)$

$! This is wrong because it applies foo to each element of the map!$
$FOO:foo(); separator = "\n"$

$! This is right because each element of baz is itself a map! !$
$FIZZBUZZ:foo(); separator = "\n"$
$FIZZBUZZ:bar(); separator = "\n"$
>>

foo(nn) ::= <<
foo: $nn.name; null="NULL"$ . $nn.national; null="NULL"$
>>


bar(mm) ::= <<
bar: $mm.name$ @ $mm.national$
>>

您将得到以下输出:

foo: Nick . German
bar: Karl @ French

foo: NULL . NULL
foo: NULL . NULL

foo: Kitty . English
foo: Dan . Finnish
bar: Kitty @ English
bar: Dan @ Finnish

因此,只需将您的调用从 FOO:foo() 更改为 foo(nn=FOO)

我使用了小 StringTemplate我开发的应用程序引擎项目(http://stringtemplate.appspot.com/)来测试这个;我认为它使用的不是 4.0 版本而是 3.2 版本,但应该非常相似。

Your problem is that you are applying the foo / bar templates to each item in the map rather than to the map itself.

Consider the following data structure:

{
  "FOO": {
    "name": "Nick",
    "national":"German"
  },
  "BAR": {
    "name": "Karl",
    "national":"French"
  },
  "FIZZBUZZ": [
    {
      "name": "Kitty",
      "national":"English"
    },
    {
      "name": "Dan",
      "national":"Finnish"
    }
  ]
}

(Imagine that you've set FOO to be the resulting map, FIZZBUZZ, etc.).

And imagine the following templates:

group blank;
main()::=<<
$foo(nn=FOO)$
$bar(mm=BAR)$

$! This is wrong because it applies foo to each element of the map!$
$FOO:foo(); separator = "\n"$

$! This is right because each element of baz is itself a map! !$
$FIZZBUZZ:foo(); separator = "\n"$
$FIZZBUZZ:bar(); separator = "\n"$
>>

foo(nn) ::= <<
foo: $nn.name; null="NULL"$ . $nn.national; null="NULL"$
>>


bar(mm) ::= <<
bar: $mm.name$ @ $mm.national$
>>

You will get the following output:

foo: Nick . German
bar: Karl @ French

foo: NULL . NULL
foo: NULL . NULL

foo: Kitty . English
foo: Dan . Finnish
bar: Kitty @ English
bar: Dan @ Finnish

So just change your call from FOO:foo() to foo(nn=FOO)

I used the little StringTemplate app engine project I developed (http://stringtemplate.appspot.com/) to test this; it's not using version 4.0 but 3.2 I think, but it should be very similar.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文