Details

Page Contents

Default handlers

对于某些 XML 节点类型,有一个默认处理程序,如果您尚未为该节点定义处理程序(即,如果没有与该节点名称相同的用户定义指令可用),它将处理该节点。以下是这些节点类型以及默认处理程序的作用:

元素和属性节点将根据通常的 XML 独立机制进行处理。也就是说,@node_type将被称为处理程序,如果未定义该处理程序,则错误将停止模板处理。

对于元素节点,这意味着如果定义一个名为@element的宏(或其他类型的用户定义的指令),它将捕获所有元素节点,而该节点没有更多特定的处理程序。如果没有@element处理程序,则必须为所有可能的元素定义一个处理程序。

recurse指令不访问属性节点,因此您无需为其编写处理程序。

访问单个节点

使用visit directive,您可以访问单个节点,而不是该节点的子节点:<#visit nodeToVisist>。有时这可能很有用。

XML namespaces

我们说过,元素的处理程序用户定义指令(如宏)的名称就是该元素的名称。实际上,它是元素的标准名称:prefix:elementName。有关使用prefix -es 的规则与命令处理相同。因此,用户定义的book指令仅处理不属于任何 XML 名称空间的元素book(除非您指定了默认的 XML 名称空间)。因此,如果示例 XML 将使用 XML 命名空间http://example.com/ebook

<book xmlns="http://example.com/ebook">
...

然后,FTL 应该如下所示:

<#ftl ns_prefixes={"e":"http://example.com/ebook"}>

<#recurse doc>

<#macro "e:book">
  <html>
    <head>
      <title><#recurse .node["e:title"]></title>
    </head>
    <body>
      <h1><#recurse .node["e:title"]></h1>
      <#recurse>
    </body>
  </html>
</#macro>

<#macro "e:chapter">
  <h2><#recurse .node["e:title"]></h2>
  <#recurse>
</#macro>

<#macro "e:para">
  <p><#recurse>
</#macro>

<#macro "e:title">
  <#--
    We have handled this element imperatively,
    so we do nothing here.
  -->
</#macro>

<#macro @text>${.node?html}</#macro>

或者,您可以定义一个默认的 XML 名称空间,然后模板的其他部分与原始 XML 名称空间免费示例中的相同:

<#ftl ns_prefixes={"D":"http://example.com/ebook"}>

<#recurse doc>

<#macro book>
...

但是在这种情况下,请不要在 XPath 表达式中伪造(我们在示例中未使用任何东西),必须使用显式的D:访问默认的 XML 名称空间,因为没有前缀的名称始终引用 XPath 中没有 XML 名称空间的节点。还要注意,使用与命令式 XML 处理相同的逻辑,如果(且仅当)存在默认的 XML 名称空间时,不具有 XML 名称空间的元素的处理程序名称为N:elementName。但是,对于非元素类型的节点(例如文本节点),切勿在处理程序名称中使用N前缀,因为这些节点没有 XML 名称空间的概念。因此,例如,文本节点的处理程序始终只是@text

有关更多详细信息,请阅读递归和访问的参考指令。

上一章 首页 下一章