【问题标题】:Using Mustache Template with XML将 Mustache 模板与 XML 一起使用
【发布时间】:2021-03-20 02:53:15
【问题描述】:

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

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

例如,我可能需要根据数据输入生成两个 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>

那么空班还有一个学生区。

例如

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

如果我移动循环:

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

我将在第一个示例中重复学生:

例如

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

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

【问题讨论】:

    标签: templates mustache


    【解决方案1】:

    我找到了自己问题的答案。使用 JMustache,模板应如下所示:

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

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

    因此,上述代码在循环学生循环中的第一个条目时只会输出&lt;students&gt;。同样&lt;/students&gt; 只会在进入学生循环时输出。

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

    【讨论】:

    • 可以用来生成XML属性吗?
    • 是的,它与输出格式无关。它会吐出您拥有 {{VAR}} 的值。
    【解决方案2】:

    我建议两种情况的方法:

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

    如何呈现 null 或空列表

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

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

    将呈现给:

    <!-- No students found --->
    

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

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

    如何呈现非空列表

    Mustache 的 Non-Empty Lists 将列出所有 studentseach 名称包含在 &lt;students&gt;&lt;/students&gt; 集合中。

    但您只希望包装集合元素&lt;students&gt; 在列表中出现一次。然后,您可以根据您的模型是 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>
    

    好处:

    • 更简洁易读的模板
    • 两种不同的情况被分开并明确传达

    【讨论】:

    • 我认为这比使用-first-last 更清楚。
    【解决方案3】:

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

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

    如果“students”存在且非空,则将呈现标记之间的内容。否则会被忽略。

    “。” character 是一个自引用 - 在“students”块中,它指的是students 集合本身。

    “?”不是“官方”Mustache 语法,但如果 JMustache 不是硬性要求,则可能是一种选择。

    【讨论】:

    • 多么大的转变!然后(2020 年 11 月)推荐你的工具,最近你写了一篇关于快速 Mustache 用于 XML 模板的优秀文章:DZone(2021 年 1 月):Transforming XML with Mustache Templates?️
    • @hc_dev 你能详细说明你的评论吗?这个建议是为了回应 OP 关于使用模板生成 XML 的问题。您提到的文章恰恰相反——它使用模板将 XML 转换为另一种表示形式。
    • 我认为 OP 的问题非常以 JMustache 为中心(标题、标签、正文)。因此,在我看来,您暗示另一种依赖关系的答案与此相去甚远。但我喜欢您与 Mustache 相关的文章,并希望鼓励您使用 Mustache 提供答案。对不起,如果我的评论有误导性?
    • 谢谢。我更新了我的答案以澄清意图。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-11
    • 2019-02-01
    • 2016-06-02
    • 1970-01-01
    相关资源
    最近更新 更多