使用带有XML的胡子模板

时间:2017-12-26 23:01:27

标签: templates mustache

我正在使用JMustache,但我想这个问题对于所有实现都是一样的。

我使用Mustache生成XML文件。当列表为空时,我不希望显示父标记。当列表不为空时,我希望父标记显示一次。我想知道胡子模板应该是什么样子。

例如,我可能需要根据数据输入生成两个XML文件中的任何一个:

<class>
    <name>Basketweaving</name>
    <students>
        <student>Joe Smith</student> 
        <student>Sally Smithers</student>
    </students>
</class>

或:

<class>
    <name>Basketweaving at a bad time</name>
</class>

我遇到的问题是,如果我这样定义我的模板:

<class>
   <name>{{className}}</name>
   <students>
    {{#students}}
      <student>{{studentName}}</student>
    {{/students}}
   </students>
<class>

然后空课仍然有学生阻止。

e.g。

  <class>
        <name>Basketweaving at a bad time</name>
        <students>
</students>
    </class>

如果我移动循环:

<class>
   <name>{{className}}</name>
   {{#students}}
   <students>
      <student>{{studentName}}</student>
   </students>
   {{/students}}
<class>

我最后会在第一个例子中重复学生:

e.g。

<class>
    <name>Basketweaving</name>
    <students>
        <student>Joe Smith</student> 
    </students>
    <students>
        <student>Sally Smithers</student>
    </students>
</class>

那么,做模板以获得我想要的行为的正确方法是什么?

3 个答案:

答案 0 :(得分:1)

我建议采用两种情况的方法:

  1. 空列表或空列表被简单地省略
  2. 非空列表与其元素一起呈现

如何呈现空列表或空列表

Mustache 的 Inverted Section 可以呈现“没有找到”的情况(例如错误消息或一些替代元素):

   {{^students}}
<!-- No students found --->
   {{/students}}

将呈现为:

<!-- No students found --->

但在你的情况下,你什么都不想要:

{{^students}}{{/students}}

如何呈现非空列表

Mustache 的 Non-Empty Lists 会列出 每个 的所有 students,名称包含在 <students></students> 集合中。

但您只希望包装集合元素 <students> 为列表出现一次。然后,您可以根据您的模型是 array 或 list 来测试 length 或 size 属性:

{{#students.length}}
    <students>
    {{#students}}
        <student>{{studentName}}</student>
    {{/students}}
    </students>
{{/students.length}}

将导致例如:

    <students>
        <student>Joe Smith</student> 
        <student>Sally Smithers</student>
    </students>

length-conditional 的灵感来自当前对类似问题的最高/已接受答案: How to handle string or array of strings in mustache template

将两种情况放在一起

所以我们在外层 class root-element 中添加两个模板部分,并且始终存在子 name

<class>
   <name>{{className}}</name>
{{#students.length}}
    <students>
    {{#students}}
        <student>{{studentName}}</student>
    {{/students}}
    </students>
{{/students.length}}
{{^students}}{{/students}}
<class>

优点:

  • 更清晰易读的模板
  • 将两种不同的情况分开并明确传达

答案 1 :(得分:0)

我找到了自己问题的答案。使用JMustache,模板应该类似于以下内容:

<class>
   <name>{{className}}</name>
   {{#students}}
   {{#-first}}<students>{{/-first}}
      <student>{{studentName}}</student>
   {{#-last}}</students>{{/-last}}
   {{/students}}
<class>

-first和-last是特殊标志,仅在循环的第一次或最后一次迭代时才为真。

因此,上面的代码只会在循环学生循环中的第一个条目时输出<students>。同样,</students>只会在学生循环输入期间输出。

这意味着如果学生是空列表,则永远不会输出<students> </students>,但如果有一个或多个条目,则条目将被<students> </students>包围。

答案 2 :(得分:0)

使用HTTP-RPC项目中的TemplateEncoder类(我是作者),您可以这样做:

<class>
   <name>{{className}}</name>
   {{?students}}
   <students>
      {{#.}}
      <student>{{studentName}}</student>
      {{/.}}
   </students>
   {{/students}}
<class>

如果“学生”存在且为非空,则将渲染标记之间的内容。否则,它将被忽略。

“。”角色是一种自我参照-在“学生”部分中,它指的是学生收藏本身。

如果替换“?”,在JMustache中类似的工作可能会起作用。带有“#”(尽管我还没有尝试过)。