freemarker / 2.3.28 / reference / xgui_imperative_formal.html

Details

对应于 DOM 树中单个节点的每个变量都是类型为 node 和类型为 hash 的多类型变量(对于程序员:实现TemplateNodeModelTemplateHashModel)。因此,您可以将node built-ins与它们一起使用。哈希键被解释为 XPath 表达式,下表中显示的特殊键除外。一些节点变量也具有字符串类型,因此您可以将它们用作字符串变量(对于程序员:它们实现TemplateScalarModel)。

节点类型(?node_type) 节点名称(?node_name) 字符串值(例如<p>${node}) 特殊哈希键
"document" "@document" 没有字符串值。 (尝试将其用作字符串时出错.) elementName , "prefix:elementName" , * , ** , @@markup , @@nested_markup , @@text , @@local_name , @@qname , @@namespace
"element" "name":元素的名称。这是本地名称(即没有名称空间前缀的名称)。 如果没有元素子级,则所有文本节点子级的文本都串联在一起。否则,当您尝试将其用作字符串时出错。 elementName , "prefix:elementName" , * , ** , @attrName , "@prefix:attrName" , @@ , "@*" , @@start_tag , @@end_tag , @@attributes_markup , @@next_sibling_element , @@previous_sibling_element , @@markup , @@nested_markup , @@text , @@local_name , @@qname , @@namespace
"text" "@text" Literals 本身。 @@markup , @@nested_markup , @@text , @@local_name , @@qname , @@namespace
"pi" "@pi$target" 目标名称和?>之间的部分。 @@markup , @@nested_markup , @@text , @@local_name , @@qname , @@namespace
"comment" "@comment" Comments 文本,不包含定界符<!----> @@markup , @@nested_markup , @@text , @@local_name , @@qname , @@namespace
"attribute" "name":属性名称。这是本地名称(即没有名称空间前缀的名称)。 属性的值。 @@markup , @@nested_markup , @@text , @@qname , @@local_name , @@qname , @@namespace
"document_type" "@document_type$name"name是文档元素的名称。 没有字符串值。 (尝试将其用作字符串时出错.) @@markup , @@nested_markup , @@text , @@local_name , @@qname , @@namespace

Notes:

  • 没有 CDATA 类型。 CDATA 节点被透明地视为文本节点。

  • 这些变量支持?keys?values

  • 元素和属性节点名称是本地名称,也就是说,它们不包含名称空间前缀。可以使用内置的?node_namespace来查询节点所属的名称空间的 URI。

  • XPath 表达式需要 Jaxen(推荐,但请使用 1.1-beta-8 或更高版本; 在这里下载)或可用的 Apache Xalan 类,否则错误将停止模板执行。但是请注意,由于某些特殊的哈希键隐藏了具有相同含义的 XPath 表达式,即使没有可用的 XPath 实现,这些 XPath 表达式也将起作用。如果 Xalan 和 Jaxen 都可用,除非您通过从 Java 调用freemarker.ext.dom.NodeModel.useJaxenXPathSupport()选择 Jaxen,否则 FreeMarker 将使用 Xalan。

  • 如果 Jaxen 用于 XPath 支持(不是 Xalan),则 FreeMarker 变量与 XPath 变量引用(例如doc["book/chapter[title=$currentTitle]"])一起可见。

特殊哈希键的含义:

  • elementName"prefix:elementName":返回作为名称elementName的元素的子节点的序列。 (请注意,术语“子”表示“立即”后代.)该选择具有 XML 名称空间感知能力,除非 XML 文档使用了不处于名称空间感知模式的 XML 解析器。在 XML 名称空间感知模式下,不带前缀的名称(* elementName )仅选择不属于任何 XML 命名空间的元素(除非您已注册默认的 XML 名称空间),以及带前缀的名称( prefix *: * elementName *)仅选择属于该前缀表示的 XML 名称空间的元素。前缀的注册和默认 XML 名称空间的设置是通过ftl directivens_prefixes参数完成的。

  • *:返回所有子(直接后代)* element *节点的序列。该序列将包含“文档 Sequences”中的元素,即每个节点的 XML 表示形式的第一个字符出现的 Sequences(在扩展通用实体之后)。

  • **:返回所有后代* element *节点的序列。该序列将按文档 Sequences 包含元素。

  • @attName"@prefix:attrName":将元素的属性attName作为包含属性节点的大小为 1 的序列返回,或者如果属性不存在则作为空序列返回(要检查属性是否存在,请使用foo.@attName[0]?? foo.@attName??) 。与特殊键"elementName"一样,如果序列的长度为 1,则它也将作为其第一个子变量。如果未使用prefix,则它将仅返回不使用 XML 名称空间的属性(即使您已设置默认的 XML 名称空间)。如果使用prefix,则它仅返回属于与prefix关联的 XML 名称空间的属性。前缀的注册通过ftl directivens_prefixes参数完成。

  • @@"@*":返回属于父元素的属性节点的序列。这与 XPath @*相同。

  • @@qname:返回元素的全限定名称(例如e:book,而不是?node_name返回的本地名称book)。使用的前缀(作为e)是根据在当前名称空间中使用ftl指令的ns_prefixes参数注册的前缀来选择的,并且不受源 XML 文档中使用的前缀的影响。如果设置了默认的 XML 名称空间,则对于使用该名称空间的节点,将使用前缀D。对于不属于 XML 名称空间的节点,不使用前缀(即使您已设置默认名称空间)。如果没有为该节点的名称空间注册前缀,则结果为不存在的变量(node.@@qname??false)。

  • @@local_mame:没有名称空间前缀的节点名称。

  • @@namespace:节点的名称空间 URL(不是名称空间前缀)。

  • @@markup:这将以字符串形式返回节点的完整 XML 标记。 (完整的 XML 标记意味着它还包含子节点的标记以及子节点的子标记,依此类推.)获得的标记与源 XML 文件中的标记不必相同,在语义上是相同的。特别是,请注意,CDATA 部分将变为纯文本。还要注意,根据您用 FreeMarker 包装原始 XML 文档的方式,Comments 或处理指令节点可能会被删除,然后它们当然会从输出中丢失。对于每个在输出 XML 片段中使用的 XML 名称空间,第一个输出的开始标记将包含xmlns:prefix属性,并且这些前缀将在输出的元素和属性名称中使用。这些前缀将与使用ftl指令的ns_prefixes参数注册的前缀相同(对于D,将不使用任何前缀,因为它将使用xmlns属性注册为默认名称空间),或者如果未分配前缀对于具有该名称的 XML 名称空间,则使用任意选择的未使用的前缀。

  • @@nested_markup:类似于@@markup,但是它返回元素的 XML 标记,但没有其打开和关闭标签。对于文档节点,它返回与@@markup相同的结果。对于其他节点类型(文本,处理指令等),它将返回一个空字符串。与@@markup不同,不会将xmlns:prefix属性放置到输出中,但是关于元素和属性名称中使用的前缀,规则是相同的。

  • @@text:这将返回节点中出现的所有文本节点(所有后代文本节点,而不仅仅是直接子节点)的值,这些值连接在一起成为单个字符串。如果该节点没有文本节点子节点,则结果为空字符串。

  • @@start_tag:返回元素节点start-tag的标记。与@@markup一样,输出不必与原始 XML 文档中的输出相同,但在语义上与之等效。关于 XML 名称空间(输出中的xmlns:prefix属性等),规则与"@@markup"相同。

  • @@end_tag:返回元素节点end-tag的标记。与@@markup一样,输出不必与原始 XML 文档中的输出相同,但在语义上与之等效。

  • @@attributes_markup:返回元素节点attributes的标记。与@@markup一样,输出不必与原始 XML 文档中的输出相同,但在语义上与之等效。

  • @@next_sibling_element(自 2.3.26 起):元素节点的以下同级元素或空节点序列(如果没有此类元素)。如果一个元素在相同的层次结构级别上,则该元素视为另一个元素的同级,并且两个元素之间没有其他元素或非空白字符数据(文本或 CDATA)。例如,在<a/><!-- comment -->&#x20;<b/>中,这两个元素是同级,而在<a/>text<b/><a/><x/><b/>中则不是。

  • @@previous_sibling_element(自 2.3.26 起):元素节点的前一个兄弟元素或空节点序列(如果没有此类元素)。有关兄弟姐妹的含义,请参见最后一点。

Node sequences

许多特殊的哈希键(在上面的列表中指示)以及导致节点集的 XPath 表达式(请参见XPath recommendation)返回节点序列。

如果这些节点序列恰好存储 1 个子变量,它们本身也将充当子变量。例如,如果元素book仅有一个title元素子元素,则${book.title[0]}将与${book.title}相同。

返回空节点序列是正常情况。例如,如果在具体的 XML 文档中,元素book没有子元素chapter,则book.chapter导致空节点序列。谨防!这也意味着book.chaptre(注意拼写错误)也将返回空节点序列,并且不会因错误而停止。另外,book.chaptre??(请注意 Importing 错误)将返回true,因为存在空序列,因此您必须使用book.chaptre[0]??进行检查。

不存储 1 个节点(但 0 个或多于 1 个节点)的节点序列也支持上述某些哈希键。即,支持以下特殊键:

  • elementName , "prefix:elementName"

  • @attrName , "@prefix:attrName"

  • @@markup , @@nested_markup

  • @@text

  • * , **

  • @@ , "@*"

当您在包含多个节点或 1 个或多个节点的节点序列上应用上述特殊键之一时,则对于序列中的每个节点(特殊键确实有意义,例如,文本节点将跳过键*@foo) ,将按对单个节点的说明应用特殊键,并将结果连接起来以形成最终结果。结果将按照节点 Sequences 出现在相应节点中的 Sequences 进行连接。串联是指字符串或序列的串联,具体取决于结果的类型。如果特殊键将导致单个节点的字符串,则对于多个节点,结果也将是单个字符串(串联的单个节点的结果),并且如果特殊键将返回单个节点的序列,则对于多个节点,结果也是单个序列。如果您在序列上应用了特殊键,则该序列中有 0 个节点,则字符串结果分别为空字符串或空序列。

XPath 表达式可以与节点序列一起使用。但是,由于 Xalan XPath 实现的局限性,对于 0 个或 1 个以上的节点,仅当您使用 Jaxen 而不是 Xalan 时,它才有效。