blob: c33c0e4f57aca89a379f23b6ba31abfaefca597a [file] [log] [blame]
<!doctype html>
<!-- Generated by FreeMarker/Docgen from DocBook -->
<html lang="en" class="page-type-section">
<head prefix="og: http://ogp.me/ns#">
<meta charset="utf-8">
<title>Legacy XML wrapper implementation - Apache FreeMarker Manual</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="format-detection" content="telephone=no">
<meta property="og:site_name" content="Apache FreeMarker Manual">
<meta property="og:title" content="Legacy XML wrapper implementation">
<meta property="og:locale" content="en_US">
<meta property="og:url" content="https://freemarker.apache.org/docs/pgui_misc_xml_legacy.html">
<link rel="canonical" href="https://freemarker.apache.org/docs/pgui_misc_xml_legacy.html">
<link rel="icon" href="favicon.png" type="image/png">
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto:500,700,400,300|Droid+Sans+Mono">
<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1707770044859">
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/cookie-bar/cookiebar-latest.min.js"></script>
</head>
<body itemscope itemtype="https://schema.org/Code">
<meta itemprop="url" content="https://freemarker.apache.org/docs/">
<meta itemprop="name" content="Apache FreeMarker Manual">
<!--[if lte IE 9]>
<div class="oldBrowserWarning" style="display: block">
Unsupported web browser - Use a modern browser to view this website!
</div>
<![endif]--> <div class="oldBrowserWarning">
Unsupported web browser - Use a modern browser to view this website!
</div>
<div class="header-top-bg"><div class="site-width header-top"><div id="hamburger-menu" role="button"></div> <div class="logo">
<a href="https://freemarker.apache.org" role="banner"><img itemprop="image" src="logo.png" alt="FreeMarker"></a> </div>
<ul class="tabs"><li><a href="https://freemarker.apache.org/">Home</a></li><li class="current"><a href="index.html">Manual</a></li><li><a class="external" href="api/index.html">Java API</a></li></ul><ul class="secondary-tabs"><li><a class="tab icon-heart" href="https://freemarker.apache.org/contribute.html" title="Contribute"><span>Contribute</span></a></li><li><a class="tab icon-bug" href="https://issues.apache.org/jira/projects/FREEMARKER" title="Report a Bug"><span>Report a Bug</span></a></li><li><a class="tab icon-download" href="https://freemarker.apache.org/freemarkerdownload.html" title="Download"><span>Download</span></a></li></ul></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">Manual</a><div class="navigation-header"></div><form method="get" class="search-form" action="search-results.html"><fieldset><legend class="sr-only">Search form</legend><label for="search-field" class="sr-only">Search query</label><input id="search-field" name="q" type="search" class="search-input" placeholder="Search" spellcheck="false" autocorrect="off" autocomplete="off"><button type="submit" class="search-btn"><span class="sr-only">Search</span></button></fieldset></form></div><div class="site-width breadcrumb-row"> <div class="breadcrumbs">
<ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">Apache FreeMarker Manual</span></a></li><li class="step-1" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="pgui.html"><span itemprop="name">Programmer&#39;s Guide</span></a></li><li class="step-2" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="pgui_misc.html"><span itemprop="name">Miscellaneous</span></a></li><li class="step-3" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="pgui_misc_xml_legacy.html"><span itemprop="name">Legacy XML wrapper implementation</span></a></li></ul> </div>
<div class="bookmarks" title="Bookmarks"><span class="sr-only">Bookmarks:</span><ul><li><a href="alphaidx.html">Alpha. index</a></li><li><a href="gloss.html">Glossary</a></li><li><a href="dgui_template_exp.html#exp_cheatsheet">Expressions</a></li><li><a href="ref_builtins_alphaidx.html">?builtins</a></li><li><a href="ref_directive_alphaidx.html">#directives</a></li><li><a href="ref_specvar.html">.spec_vars</a></li><li><a href="app_faq.html">FAQ</a></li></ul></div></div></div> <div class="main-content site-width">
<div class="content-wrapper">
<div id="table-of-contents-wrapper" class="col-left">
<script>var breadcrumb = ["Apache FreeMarker Manual","Programmer\'s Guide","Miscellaneous","Legacy XML wrapper implementation"];</script>
<script src="toc.js?1707770044859"></script>
<script src="docgen-resources/main.min.js?1707770044859"></script>
</div>
<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="pgui_misc_secureenv.html"><span>Previous</span></a><a class="paging-arrow next" href="pgui_misc_ant.html"><span>Next</span></a></div><div class="title-wrapper">
<h1 class="content-header header-section1" id="pgui_misc_xml_legacy" itemprop="headline">Legacy XML wrapper implementation</h1>
</div></div><div class="page-menu">
<div class="page-menu-title">Page Contents</div>
<ul><li><a class="page-menu-link" href="#autoid_65" data-menu-target="autoid_65">TemplateScalarModel</a></li><li><a class="page-menu-link" href="#autoid_66" data-menu-target="autoid_66">TemplateCollectionModel</a></li><li><a class="page-menu-link" href="#autoid_67" data-menu-target="autoid_67">TemplateSequenceModel</a></li><li><a class="page-menu-link" href="#autoid_68" data-menu-target="autoid_68">TemplateHashModel</a></li><li><a class="page-menu-link" href="#autoid_69" data-menu-target="autoid_69">TemplateMethodModel</a></li><li><a class="page-menu-link" href="#autoid_70" data-menu-target="autoid_70">Namespace handling</a></li></ul> </div> <div class="callout note">
<strong class="callout-label">Note:</strong>
<p><em>The legacy XML wrapper is deprecated.</em>
FreeMarker 2.3 has introduced support for a new XML processing
model. To support this, a new XML wrapper package was introduced,
<code class="inline-code">freemarker.ext.dom</code>. For new usage, we encourage
you to use that. It is documented in the part <a href="xgui.html">XML Processing Guide</a>.</p>
</div>
<p>The class <code class="inline-code">freemarker.ext.xml.NodeListModel</code>
provides a template model for wrapping XML documents represented as
node trees. Every node list can contain zero or more XML nodes
(documents, elements, texts, processing instructions, comments, entity
references, CDATA sections, etc.). The node list implements the
following template model interfaces with the following
semantics:</p>
<h2 class="content-header header-section2" id="autoid_65">TemplateScalarModel</h2>
<p>When used as a scalar, the node list will render the XML
fragment that represents its contained nodes. This makes it handy
for use in XML-to-XML transforming templates.</p>
<h2 class="content-header header-section2" id="autoid_66">TemplateCollectionModel</h2>
<p>When used as a collection with <code class="inline-code">list</code>
directive, it will simply enumerate its nodes. Every node will be
returned as a new node list consisting of a single node.</p>
<h2 class="content-header header-section2" id="autoid_67">TemplateSequenceModel</h2>
<p>When used as a sequence, it will return the i-th node as a new
node list consisting of the single requested node. I.e. to return
the 3rd <code class="inline-code">&lt;chapter&gt;</code> element of the
<code class="inline-code">&lt;book&gt;</code> element, you&#39;d use the following
(note indexes are zero-based):</p>
<div class="code-block role-template">
<div class="code-block-label">Template</div><pre class="code-block-body">&lt;#assign thirdChapter = xmldoc.book.chapter[2]&gt;</pre> </div>
<h2 class="content-header header-section2" id="autoid_68">TemplateHashModel</h2>
<p>When used as a hash, it is basically used to traverse
children. That is, if you have a node list named
<code class="inline-code">book</code> that wraps an element node with several
chapters, then the <code class="inline-code">book.chapter</code> will yield a node
list with all chapter elements of that book element. The at sign is
used to refer to attributes: <code class="inline-code">book.@title</code> yields a
node list with a single attribute node, that is the title attribute
of the book element.</p>
<p>It is important to realize the consequence that, for example,
if <code class="inline-code">book</code> has no <code class="inline-code">chapter</code>-s then
<code class="inline-code">book.chapter</code> is an empty sequence, so
<code class="inline-code">xmldoc.book.chapter??</code> will
<em>not</em> be <code class="inline-code">false</code>, it will be
always <code class="inline-code">true</code>! Similarly,
<code class="inline-code">xmldoc.book.somethingTotallyNonsense??</code> will not
be <code class="inline-code">false</code> either. To check if there was no
children found, use <code class="inline-code">xmldoc.book.chapter?size ==
0</code>.</p>
<p>The hash defines several &quot;magic keys&quot; as well. All these keys
start with an underscore. The most notable is the
<code class="inline-code">_text</code> key which retrieves the text of the node:
<code class="inline-code">${book.@title._text}</code> will render the value of the
attribute into the template. Similarly, <code class="inline-code">_name</code>
will retrieve the name of the element or attribute.
<code class="inline-code">*</code> or <code class="inline-code">_allChildren</code> returns all
direct children elements of all elements in the node list, while
<code class="inline-code">@*</code> or <code class="inline-code">_allAttributes</code> returns
all attributes of the elements in the node list. There are many more
such keys; here&#39;s a detailed summary of all the hash keys:</p>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Key name</th>
<th>Evaluates to</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="inline-code">*</code> or <code class="inline-code">_children</code></td>
<td>all direct element children of current nodes
(non-recursive). Applicable to element and document
nodes.</td>
</tr>
<tr>
<td><code class="inline-code">@*</code> or
<code class="inline-code">_attributes</code></td>
<td>all attributes of current nodes. Applicable to elements
only.</td>
</tr>
<tr>
<td><code class="inline-code">@<em class="code-color">attributeName</em></code></td>
<td>named attributes of current nodes. Applicable to elements,
doctypes and processing instructions. On doctypes it supports
attributes <code class="inline-code">publicId</code>,
<code class="inline-code">systemId</code> and
<code class="inline-code">elementName</code>. On processing instructions, it
supports attributes <code class="inline-code">target</code> and
<code class="inline-code">data</code>, as well as any other attribute name
specified in data as <code class="inline-code">name=&quot;value&quot;</code> pair. The
attribute nodes for doctype and processing instruction are
synthetic, and as such have no parent. Note, however that
<code class="inline-code">@*</code> does NOT operate on doctypes or
processing instructions.</td>
</tr>
<tr>
<td><code class="inline-code">_ancestor</code></td>
<td>all ancestors up to root element (recursive) of current
nodes. Applicable to same node types as
<code class="inline-code">_parent</code>.</td>
</tr>
<tr>
<td><code class="inline-code">_ancestorOrSelf</code></td>
<td>all ancestors of current nodes plus current nodes.
Applicable to same node types as
<code class="inline-code">_parent</code>.</td>
</tr>
<tr>
<td><code class="inline-code">_content</code></td>
<td>the complete content of current nodes, including children
elements, text, entity references, and processing instructions
(non-recursive). Applicable to elements and documents.</td>
</tr>
<tr>
<td><code class="inline-code">_descendant</code></td>
<td>all recursive descendant element children of current
nodes. Applicable to document and element nodes.</td>
</tr>
<tr>
<td><code class="inline-code">_descendantOrSelf</code></td>
<td>all recursive descendant element children of current nodes
plus current nodes. Applicable to document and element
nodes.</td>
</tr>
<tr>
<td><code class="inline-code">_document</code></td>
<td>all documents the current nodes belong to. Applicable to
all nodes except text.</td>
</tr>
<tr>
<td><code class="inline-code">_doctype</code></td>
<td>doctypes of the current nodes. Applicable to document
nodes only.</td>
</tr>
<tr>
<td><code class="inline-code">_filterType</code></td>
<td>is a filter-by-type template method model. When called, it
will yield a node list that contains only those current nodes
whose type matches one of types passed as argument. You should
pass arbitrary number of strings to this method containing the
names of types to keep. Valid type names are: &quot;attribute&quot;,
&quot;cdata&quot;, &quot;comment&quot;, &quot;document&quot;, &quot;documentType&quot;, &quot;element&quot;,
&quot;entity&quot;, &quot;entityReference&quot;, &quot;processingInstruction&quot;,
&quot;text&quot;.</td>
</tr>
<tr>
<td><code class="inline-code">_name</code></td>
<td>the names of current nodes, one string per node
(non-recursive). Applicable to elements and attributes
(returns their local names), entities, processing instructions
(returns its target), doctypes (returns its public ID)</td>
</tr>
<tr>
<td><code class="inline-code">_nsprefix</code></td>
<td>the namespace prefixes of current nodes, one string per
node (non-recursive). Applicable to elements and
attributes</td>
</tr>
<tr>
<td><code class="inline-code">_nsuri</code></td>
<td>the namespace URIs of current nodes, one string per node
(non-recursive). Applicable to elements and attributes</td>
</tr>
<tr>
<td><code class="inline-code">_parent</code></td>
<td>parent elements of current nodes. Applicable to element,
attribute, comment, entity, processing instruction.</td>
</tr>
<tr>
<td><code class="inline-code">_qname</code></td>
<td>the qualified names of current nodes in
<code class="inline-code">[namespacePrefix:]localName</code> form, one
string per node (non-recursive). Applicable to elements and
attributes</td>
</tr>
<tr>
<td><code class="inline-code">_registerNamespace(prefix, uri)</code></td>
<td>register a XML namespace with the specified prefix and URI
for the current node list and all node lists that are derived
from the current node list. After registering, you can use the
<code class="inline-code">nodelist[&quot;prefix:localname&quot;]</code>, or
<code class="inline-code">nodelist[&quot;@prefix:localname&quot;]</code> syntax (or
<code class="inline-code">nodelist.prefix\:localname</code>, or
<code class="inline-code">nodelist.@prefix\:localname</code>) to reach
elements, and attributes whose names are namespace-scoped.
Note that the namespace prefix need not match the actual
prefix used by the XML document itself since namespaces are
compared solely by their URI. Also note that if you do
<code class="inline-code">doc.elem1._registerNamespace(<em class="code-color">...</em>)</code>,
and then later you use <code class="inline-code">doc.elem1</code> again, it
will not have the prefix registered, because each time you use
<code class="inline-code">doc.elem1</code>, it gives a completely new
object. In this example, you certainly should have used
<code class="inline-code">doc._registerNamespace(<em class="code-color">...</em>)</code>.</td>
</tr>
<tr>
<td><code class="inline-code">_text</code></td>
<td>the text of current nodes, one string per node
(non-recursive). Applicable to elements, attributes, comments,
processing instructions (returns its data) and CDATA sections.
The reserved XML characters (&#39;&lt;&#39; and &#39;&amp;&#39;) are not
escaped.</td>
</tr>
<tr>
<td><code class="inline-code">_type</code></td>
<td>Returns a node list containing one string per node
describing the type of the node. Possible node type names are:
&quot;attribute&quot;, &quot;cdata&quot;, &quot;comment&quot;, &quot;document&quot;, &quot;documentType&quot;,
&quot;element&quot;, &quot;entity&quot;, &quot;entityReference&quot;,
&quot;processingInstruction&quot;, &quot;text&quot;. If the type of the node is
unknown, returns &quot;unknown&quot;.</td>
</tr>
<tr>
<td><code class="inline-code">_unique</code></td>
<td>a copy of the current nodes that keeps only the first
occurrence of every node, eliminating duplicates. Duplicates
can occur in the node list by applying uptree-traversals
<code class="inline-code">_parent</code>, <code class="inline-code">_ancestor</code>,
<code class="inline-code">_ancestorOrSelf</code>, and
<code class="inline-code">_document</code>. I.e.
<code class="inline-code">foo._children._parent</code> will return a node
list that has duplicates of nodes in foo - each node will have
the number of occurrences equal to the number of its children.
In these cases, use
<code class="inline-code">foo._children._parent._unique</code> to eliminate
duplicates. Applicable to all node types.</td>
</tr>
<tr>
<td>any other key</td>
<td>element children of current nodes with name matching the
key. This allows for convenience child traversal in
<code class="inline-code">book.chapter.title</code> style syntax. Note that
<code class="inline-code">nodeset.childname</code> is technically equivalent
to <code class="inline-code">nodeset(&quot;childname&quot;)</code>, but is both
shorter to write and evaluates faster. Applicable to document
and element nodes.</td>
</tr>
</tbody>
</table>
</div>
<h2 class="content-header header-section2" id="autoid_69">TemplateMethodModel</h2>
<p>When used as a method model, it returns a node list that is
the result of evaluating an XPath expression on the current contents
of the node list. For this feature to work, you must have the
<code class="inline-code">Jaxen</code> library in your classpath. For
example:</p>
<div class="code-block role-template">
<div class="code-block-label">Template</div><pre class="code-block-body">&lt;#assign firstChapter=xmldoc(&quot;//chapter[first()]&quot;)&gt;</pre> </div>
<h2 class="content-header header-section2" id="autoid_70">Namespace handling</h2>
<p>For purposes of traversal of children elements that have
namespace-scoped names, you can register namespace prefixes with the
node list. You can do it either in Java, calling the</p>
<div class="code-block role-unspecified">
<pre class="code-block-body">public void registerNamespace(String prefix, String uri);</pre> </div>
<p>method, or inside a template using the</p>
<div class="code-block role-template">
<div class="code-block-label">Template</div><pre class="code-block-body">${<em>nodelist</em>._registerNamespace(<em>prefix</em>, <em>uri</em>)}</pre> </div>
<p>syntax. From there on, you can refer to children elements in
the namespace denoted by the particular URI through the
syntax</p>
<pre class="metaTemplate"><code class="inline-code"><em class="code-color">nodelist</em>[&quot;<em class="code-color">prefix</em>:<em class="code-color">localName</em>&quot;]</code></pre>
<p>and</p>
<pre class="metaTemplate"><code class="inline-code"><em class="code-color">nodelist</em>[&quot;@<em class="code-color">prefix</em>:<em class="code-color">localName</em>&quot;]</code></pre>
<p>as well as use these namespace prefixes in XPath expressions.
Namespaces registered with a node list are propagated to all node
lists that are derived from the original node list. Note also that
namespaces are matched by their URI only, so you can safely use a
prefix for a namespace inside your template that differs from the
prefix in the actual XML document - a prefix is just a local alias
for the URI both in the template and in the XML document.</p>
<div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="pgui_misc_secureenv.html"><span>Previous</span></a><a class="paging-arrow next" href="pgui_misc_ant.html"><span>Next</span></a></div></div></div></div> </div>
</div>
<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"><div class="column"><h3 class="column-header">Overview</h3><ul><li><a href="https://freemarker.apache.org/">What is FreeMarker?</a></li><li><a href="https://freemarker.apache.org/freemarkerdownload.html">Download</a></li><li><a href="app_versions.html">Version history</a></li><li><a href="app_faq.html">FAQ</a></li><li><a itemprop="license" href="app_license.html">License</a></li><li><a href="https://privacy.apache.org/policies/privacy-policy-public.html">Privacy policy</a></li></ul></div><div class="column"><h3 class="column-header">Often used / Reference</h3><ul><li><a href="https://try.freemarker.apache.org/">Try template online</a></li><li><a href="dgui_template_exp.html#exp_cheatsheet">Expressions cheatsheet</a></li><li><a href="ref_directive_alphaidx.html">#directives</a></li><li><a href="ref_builtins_alphaidx.html">?built_ins</a></li><li><a href="ref_specvar.html">.special_vars</a></li><li><a href="api/freemarker/core/Configurable.html#setSetting-java.lang.String-java.lang.String-">Configuration settings</a></li></ul></div><div class="column"><h3 class="column-header">Community</h3><ul><li><a href="https://github.com/apache/freemarker">Github project page</a></li><li><a href="https://issues.apache.org/jira/projects/FREEMARKER">Report a bug</a></li><li><a href="https://freemarker.apache.org/report-security-vulnerabilities.html">Report security vulnerability</a></li><li><a href="https://stackoverflow.com/questions/ask?tags=freemarker">Get help on StackOverflow</a></li><li><a href="https://twitter.com/freemarker">Announcements on Twitter</a></li><li><a href="https://freemarker.apache.org/mailing-lists.html">Discuss on mailing lists</a></li></ul></div></div><div class="col-right"><ul class="social-icons"><li><a class="github" href="https://github.com/apache/freemarker">Github</a></li><li><a class="twitter" href="https://twitter.com/freemarker">Twitter</a></li><li><a class="stack-overflow" href="https://stackoverflow.com/questions/ask?tags=freemarker">Stack Overflow</a></li></ul><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
Last generated:
<time itemprop="dateModified" datetime="2024-02-12T20:34:04Z" title="Monday, February 12, 2024 at 8:34:04 PM Greenwich Mean Time">2024-02-12 20:34:04 GMT</time>, for Freemarker 2.3.32 </p>
<p class="copyright">
© <span itemprop="copyrightYear">1999</span>–2024
<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a>. Apache FreeMarker, FreeMarker, Apache Incubator, Apache, the Apache FreeMarker logo are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners. </p>
</div></div></div></body>
</html>