On this page
Details
对应于 DOM 树中单个节点的每个变量都是类型为 node 和类型为 hash 的多类型变量(对于程序员:实现TemplateNodeModel
和TemplateHashModel
)。因此,您可以将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 directive的ns_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 directive的ns_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 --> <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 时,它才有效。