| <!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>Learning by example - 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="FreeMarker Manual"> |
| <meta property="og:title" content="Learning by example"> |
| <meta property="og:locale" content="en_US"> |
| <meta property="og:url" content="http://example.com/xgui_imperative_learn.html"> |
| <link rel="canonical" href="http://example.com/xgui_imperative_learn.html"> |
| <link rel="icon" href="favicon.png" type="image/png"> |
| <link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338517553"> |
| </head> |
| <body itemscope itemtype="https://schema.org/Code"> |
| <meta itemprop="url" content="http://example.com/"> |
| <meta itemprop="name" content="FreeMarker Manual"> |
| |
| <!--[if lte IE 9]> |
| <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div> |
| <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo"> |
| </a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><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">FreeMarker Manual</span></a></li><li class="step-1" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="xgui.html"><span itemprop="name">XML Processing Guide</span></a></li><li class="step-2" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="xgui_imperative.html"><span itemprop="name">Imperative XML processing</span></a></li><li class="step-3" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="xgui_imperative_learn.html"><span itemprop="name">Learning by example</span></a></li></ul><div class="bookmarks" title="Bookmarks"><span class="sr-only">Bookmarks:</span><ul class="bookmark-list"><li><a href="alphaidx.html">Index</a></li><li><a href="gloss.html">Glossary</a></li><li><a href="ref.html">Reference</a></li><li><a href="app_faq.html">FAQ</a></li><li><a href="preface.html#test_target">Bőregér</a></li></ul></div></div></div> <div class="main-content site-width"> |
| <div class="content-wrapper no-toc"> |
| <div id="table-of-contents-wrapper" class="col-left"> |
| </div> |
| <div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="xgui_imperative.html"><span>Previous</span></a><a class="paging-arrow next" href="xgui_imperative_formal.html"><span>Next</span></a></div><div class="title-wrapper"> |
| <h1 class="content-header header-section1" id="xgui_imperative_learn" itemprop="headline">Learning by example</h1> |
| </div></div><div class="page-menu"> |
| <div class="page-menu-title">Page Contents</div> |
| <ul><li><a class="page-menu-link" href="#autoid_68" data-menu-target="autoid_68">Accessing elements by name</a></li><li><a class="page-menu-link" href="#autoid_69" data-menu-target="autoid_69">Accessing attributes</a></li><li><a class="page-menu-link" href="#autoid_70" data-menu-target="autoid_70">Exploring the tree</a></li><li><a class="page-menu-link" href="#autoid_71" data-menu-target="autoid_71">Using XPath expressions</a></li><li><a class="page-menu-link" href="#autoid_72" data-menu-target="autoid_72">XML namespaces</a></li><li><a class="page-menu-link" href="#autoid_73" data-menu-target="autoid_73">Don't forget escaping!</a></li></ul> </div> <div class="callout note"> |
| <strong class="callout-label">Note:</strong> |
| |
| <p>This section uses the DOM tree and the variable made in the |
| <a href="xgui_expose.html">previous chapter</a>.</p> |
| </div> |
| <p>Assume that the programmer has put the XML document into the |
| data-model as variable <code class="inline-code">doc</code>. This variable |
| corresponds to the root of the <a href="xgui_expose_dom.html">DOM |
| tree</a>, the ``document''. The actual variable structure behind |
| <code class="inline-code">doc</code> is wily enough, and only roughly resembles the |
| DOM tree. So instead of getting lost in the details, let's see how to |
| use it by example.</p> |
| |
| |
| |
| |
| <h2 class="content-header header-section2" id="autoid_68">Accessing elements by name</h2> |
| |
| |
| <p>This FTL prints the title of the book:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-template"><h1>${doc.book.title}</h1></pre></div> |
| |
| <p>The output will be:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-output"><h1>Test Book</h1></pre></div> |
| |
| <p>As you see, both <code class="inline-code">doc</code> and |
| <code class="inline-code">book</code> can be used as hashes; you get their child |
| nodes as subvariables. Basically, you descriptione the path by which |
| you reach the target (element <code class="inline-code">title</code>) in the DOM |
| tree. You may notice that there was some swindle above: with |
| <code class="inline-code">${doc.book.title}</code>, it seems that we instruct |
| FreeMarker to print the <code class="inline-code">title</code> element itself, but |
| we should print its child text node (check the <a href="xgui_expose_dom.html">DOM tree</a>). It still works, because |
| elements are not only hash variables, but string variables as well. |
| The scalar value of an element node is the string resulting from the |
| concatenation of all its text child nodes. However, trying to use an |
| element as scalar will cause error if the element has child |
| elements. For example <code class="inline-code">${doc.book}</code> would stop with |
| error.</p> |
| |
| <p>This FTL prints the titles of the two chapters:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-template"><h2>${doc.book.chapter[0].title}</h2> |
| <h2>${doc.book.chapter[1].title}</h2></pre></div> |
| |
| <p>Here, as <code class="inline-code">book</code> has 2 |
| <code class="inline-code">chapter</code> element children, |
| <code class="inline-code">doc.book.chapter</code> is a sequence that stores the |
| two element nodes. Thus, we can generalize the above FTL, so it |
| works with any number of chapters:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-template"><#list doc.book.chapter as ch> |
| <h2>${ch.title}</h2> |
| </#list></pre></div> |
| |
| <p>But what's if there is only one chapter? Actually, when you |
| access an element as hash subvariable, it is |
| <em>always</em> a sequence as well (not only hash and |
| string), but if the sequence contains exactly 1 item, then the |
| variable also acts as that item itself. So, returning to the first |
| example, this would print the book title as well:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-template"><h1>${doc.book[0].title[0]}</h1></pre></div> |
| |
| <p>But you know that there is exactly 1 <code class="inline-code">book</code> |
| element, and that a book has exactly 1 title, so you can omit the |
| <code class="inline-code">[0]</code>-s. |
| <code class="inline-code">${doc.book.chapter.title}</code> would work too, if the |
| book happen to have only 1 <code class="inline-code">chapter</code>-s (otherwise |
| it is ambiguous: how is it to know if the <code class="inline-code">title</code> |
| of which <code class="inline-code">chapter</code> you want? So it stops with an |
| error.). But since a book can have multiple chapters, you don't use |
| this form. If the element <code class="inline-code">book</code> has no |
| <code class="inline-code">chapter</code> child, then |
| <code class="inline-code">doc.book.chapter</code> will be a 0 length sequence, so |
| the FTL with <code class="inline-code"><#list ...></code> will still |
| work.</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">doc.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">doc.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">doc.book.chapter[0]??</code> (or |
| <code class="inline-code">doc.book.chapter?size == 0</code>). Of course you can |
| use similarly all the <a href="dgui_template_exp.html#dgui_template_exp_missing">missing value handler |
| operators</a> (e.g. |
| <code class="inline-code">doc.book.author[0]!"Anonymous"</code>), just don't |
| forget that <code class="inline-code">[0]</code>.</p> |
| |
| <div class="callout note"> |
| <strong class="callout-label">Note:</strong> |
| |
| <p>The rule with sequences of size 1 is a convenience feature |
| of the XML wrapper (implemented via multi-type FTL variables). It |
| will not work with other sequences in general.</p> |
| </div> |
| |
| |
| <p>Now we finish the example by printing all the |
| <code class="inline-code">para</code>-s of each chapter:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-template"><h1>${doc.book.title}</h1> |
| <#list doc.book.chapter as ch> |
| <h2>${ch.title}</h2> |
| <#list ch.para as p> |
| <p>${p} |
| </#list> |
| </#list></pre></div> |
| |
| <p>this will print:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-output"><h1>Test</h1> |
| <h2>Ch1</h2> |
| <p>p1.1 |
| <p>p1.2 |
| <p>p1.3 |
| <h2>Ch2</h2> |
| <p>p2.1 |
| <p>p2.2</pre></div> |
| |
| <p>The above FTL could be written more nicely as:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-template"><#assign book = doc.book> |
| <h1>${book.title}</h1> |
| <#list book.chapter as ch> |
| <h2>${ch.title}</h2> |
| <#list ch.para as p> |
| <p>${p} |
| </#list> |
| </#list></pre></div> |
| |
| <p>Finally, a ``generalized`` usage of the child selector |
| mechanism: this template lists all <code class="inline-code">para</code>-s of the |
| example XML document:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-template"><#list doc.book.chapter.para as p> |
| <p>${p} |
| </#list></pre></div> |
| |
| <p>The output will be:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-output"> <p>p1.1 |
| <p>p1.2 |
| <p>p1.3 |
| <p>p2.1 |
| <p>p2.2 |
| </pre></div> |
| |
| <p>This example shows that hash subvariables select the children |
| of a sequence of notes (just in the earlier examples that sequence |
| happened to be of size 1). In this concrete case, subvariable |
| <code class="inline-code">chapter</code> returns a sequence of size 2 (since there |
| are two <code class="inline-code">chapter</code>-s), and then subvariable |
| <code class="inline-code">para</code> selects the <code class="inline-code">para</code> child |
| nodes of all nodes in that sequence.</p> |
| |
| <p>A negative consequence of this mechanism is that things like |
| <code class="inline-code">doc.somethingNonsense.otherNonsesne.totalNonsense</code> |
| will just evaluate to an empty sequence, and you don't get any error |
| messages.</p> |
| |
| |
| |
| |
| |
| <h2 class="content-header header-section2" id="autoid_69">Accessing attributes</h2> |
| |
| |
| <p>This XML is the same as the original, except that it uses |
| attributes for the titles, instead of elements:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-unspecified"><!-- THIS XML IS USED FOR THE "Accessing attributes" CHAPTER ONLY! --> |
| <!-- Outside this chapter examples use the XML from earlier. --> |
| |
| <book title="Test"> |
| <chapter title="Ch1"> |
| <para>p1.1</para> |
| <para>p1.2</para> |
| <para>p1.3</para> |
| </chapter> |
| <chapter title="Ch2"> |
| <para>p2.1</para> |
| <para>p2.2</para> |
| </chapter> |
| </book></pre></div> |
| |
| <p>The attributes of an element can be accessed in the same way |
| as the child elements of the element, except that you put an at-sign |
| (@) before the name of the attribute:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-template"><#assign book = doc.book> |
| <h1>${book.@title}</h1> |
| <#list book.chapter as ch> |
| <h2>${ch.@title}</h2> |
| <#list ch.para as p> |
| <p>${p} |
| </#list> |
| </#list></pre></div> |
| |
| <p>This will print exactly the same as the previous |
| example.</p> |
| |
| <p>Getting attributes follows the same logic as getting child |
| elements, so the result of <code class="inline-code">ch.@title</code> above is a |
| sequence of size 1. If there were no <code class="inline-code">title</code> |
| attribute, then the result would be a sequence of size 0. So be |
| ware, using existence built-ins is tricky here too: if you are |
| curious if <code class="inline-code">foo</code> has attribute |
| <code class="inline-code">bar</code> then you have to write |
| <code class="inline-code">foo.@bar[0]??</code>. (<code class="inline-code">foo.@bar??</code> is |
| wrong, because it always returns <code class="inline-code">true</code>.) |
| Similarly, if you want a default value for the |
| <code class="inline-code">bar</code> attribute, then you have to write |
| <code class="inline-code">foo.@bar[0]!"theDefaultValue"</code>.</p> |
| |
| <p>As with child elements, you can select the attributes of |
| multiple nodes. For example, this template prints the titles of all |
| chapters:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-template"><#list doc.book.chapter.@title as t> |
| ${t} |
| </#list></pre></div> |
| |
| |
| |
| |
| |
| <h2 class="content-header header-section2" id="autoid_70">Exploring the tree</h2> |
| |
| |
| <p>This FTL will enumerate all child nodes of the book |
| element:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-template"><#list doc.book?children as c> |
| - ${c?node_type} <#if c?node_type = 'element'>${c?node_name}</#if> |
| </#list></pre></div> |
| |
| <p>this will print:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-output">- text |
| - element title |
| - text |
| - element chapter |
| - text |
| - element chapter |
| - text</pre></div> |
| |
| <p>The meaning of <code class="inline-code">?node_type</code> is probably clear |
| without explanation. There are several node types that can occur in |
| a DOM tree, such as <code class="inline-code">"element"</code>, |
| <code class="inline-code">"text"</code>, <code class="inline-code">"comment"</code>, |
| <code class="inline-code">"pi"</code>, ...etc.</p> |
| |
| <p>The <code class="inline-code">?node_name</code> returns the name of element |
| for element nodes. For other node types, it also returns something, |
| but that's mainly useful for declarative XML processing, which will |
| be discussed in a <a href="xgui_declarative.html">later |
| chapter</a>.</p> |
| |
| <p>If the book element had attributes, they would |
| <em>not</em> appear in the above list, for practical |
| reasons. But you can get a list that contains all attributes of the |
| element, with subvariable <code class="inline-code">@@</code> of the element |
| variable. If you modify the first line of the XML to this:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-unspecified"><book foo="Foo" bar="Bar" baaz="Baaz"></pre></div> |
| |
| <p>and run this FTL:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-template"><#list doc.book.@@ as attr> |
| - ${attr?node_name} = ${attr} |
| </#list></pre></div> |
| |
| <p>then you get this output (or something similar):</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-output">- baaz = Baaz |
| - bar = Bar |
| - foo = Foo</pre></div> |
| |
| <p>Returning to the listing of children, there is a convenience |
| subvariable to list only the element children of an element:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-template"><#list doc.book.* as c> |
| - ${c?node_name} |
| </#list></pre></div> |
| |
| <p>This will print:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-output">- title |
| - chapter |
| - chapter</pre></div> |
| |
| <p>You get the parent of an element with the |
| <code class="inline-code">parent</code> built-in:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-template"><#assign e = doc.book.chapter[0].para[0]> |
| <#-- Now e is the first para of the first chapter --> |
| ${e?node_name} |
| ${e?parent?node_name} |
| ${e?parent?parent?node_name} |
| ${e?parent?parent?parent?node_name}</pre></div> |
| |
| <p>This will print:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-output">para |
| chapter |
| book |
| @document</pre></div> |
| |
| <p>In the last line you have reached the root of the DOM tree, |
| the document node. It's not an element, and this is why it has that |
| strange name; don't deal with it now. Obviously, the document node |
| has no parent.</p> |
| |
| <p>You can quickly go back to the document node using the |
| <code class="inline-code">root</code> built-in:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-template"><#assign e = doc.book.chapter[0].para[0]> |
| ${e?root?node_name} |
| ${e?root.book.title}</pre></div> |
| |
| <p>This will print:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-output">@document |
| Test Book</pre></div> |
| |
| <p>For the complete list of built-ins you can use to navigate in |
| the DOM tree, read the <a href="ref_builtins_node.html">reference |
| of node built-ins</a>.</p> |
| |
| |
| |
| |
| |
| <h2 class="content-header header-section2" id="autoid_71">Using XPath expressions</h2> |
| |
| |
| <div class="callout note"> |
| <strong class="callout-label">Note:</strong> |
| |
| <p>XPath expressions work only if <a href="http://jaxen.org/">Jaxen</a> (recommended, but use |
| at least Jaxen 1.1-beta-8, not older) or <a href="http://xml.apache.org/xalan/">Apache Xalan</a> |
| classes are available. (Apache Xalan classes are included in Sun |
| J2SE 1.4, 1.5 and 1.6 (and maybe later too); no separate Xalan jar |
| is needed.)</p> |
| </div> |
| |
| |
| <p>If a hash key used with a node variable can't be interpreted |
| otherwise (see the <a href="xgui_imperative_formal.html">next |
| section</a> for the precise definition), then it will by |
| interpreted as an XPath expression. For more information on XPath, |
| please visit <a href="http://www.w3.org/TR/xpath">http://www.w3.org/TR/xpath</a>.</p> |
| |
| <p>For example, here we list the <code class="inline-code">para</code> elements |
| of the chapter with title ``Ch1'':</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-template"><#list doc["book/chapter[title='Ch1']/para"] as p> |
| <p>${p} |
| </#list></pre></div> |
| |
| <p>It will print:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-output"> <p>p1.1 |
| <p>p1.2 |
| <p>p1.3</pre></div> |
| |
| <p>The rule with sequences of length 1 (explained in earlier |
| sections) stands for XPath results as well. That is, if the |
| resulting sequence contains exactly 1 node, it also acts as the node |
| itself. For example, print the first paragraph of chapter |
| ``Ch1'':</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-template">${doc["book/chapter[title='Ch1']/para[1]"]}</pre></div> |
| |
| <p>which prints the same as:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-template">${doc["book/chapter[title='Ch1']/para[1]"][0]}</pre></div> |
| |
| <p>The context node of the XPath expression is the node (or |
| sequence of nodes) whose hash subvariable is used to issue the XPath |
| expression. Thus, this prints the same as the previous |
| example:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-template">${doc.book["chapter[title='Ch1']/para[1]"]}</pre></div> |
| |
| <p>Note that currently you can use a sequence of 0 or multiple |
| (more than 1) nodes as context only if the programmer has set up |
| FreeMarker to use Jaxen instead of Xalan.</p> |
| |
| <p>Also note that XPath indexes sequence items from 1, while FTL |
| indexes sequence items from 0. Thus, to select the first chapter, |
| the XPath expression is <code class="inline-code">"/book/chapter[1]"</code>, while |
| the FTL expression is <code class="inline-code">book.chapter[0]</code>.</p> |
| |
| <p>If the programmer has set up FreeMarker to use Jaxen instead |
| of Xalan, then FreeMarker variables are visible with XPath variable |
| references:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-template"><#assign <strong>currentTitle</strong> = "Ch1"> |
| <#list doc["book/chapter[title=<strong>$currentTitle</strong>]/para"] as p> |
| <em>...</em></pre></div> |
| |
| <p>Note that <code class="inline-code">$currentTitle</code> is not a FreeMarker |
| interpolation, as there are no <code class="inline-code">{</code> and |
| <code class="inline-code">}</code> there. That's an XPath expression.</p> |
| |
| <p>The result of some XPath expressions is not a node-set, but a |
| string, a number, or a boolean. For those XPath expressions, the |
| result is an FTL string, number, or boolean variable respectively. |
| For example, the following will count the total number of |
| <code class="inline-code">para</code> elements in the XML document, so the result |
| is a number:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-template">${x["count(//para)"]}</pre></div> |
| |
| <p>The output will be:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-output">5</pre></div> |
| |
| |
| |
| |
| |
| <h2 class="content-header header-section2" id="autoid_72">XML namespaces</h2> |
| |
| |
| |
| |
| <p>Be default, when you write something like |
| <code class="inline-code">doc.book</code>, then it will select the element with |
| name <code class="inline-code">book</code> that does not belongs to any XML |
| namespace (similarly to XPath). If you want to select an element |
| that is inside an XML namespace, you must register a prefix and use |
| that. For example, if element <code class="inline-code">book</code> is in XML |
| namespace <code class="inline-code">http://example.com/ebook</code>, then you have |
| to associate a prefix with it at the top of the template with the |
| <code class="inline-code">ns_prefixes</code> parameter of the <a href="ref_directive_ftl.html#ref.directive.ftl"><code>ftl</code> |
| directive</a>:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-template"><#ftl ns_prefixes={"e":"http://example.com/ebook"}></pre></div> |
| |
| <p>And now you can write expressions as |
| <code class="inline-code">doc["e:book"]</code>. (The usage of square bracket |
| syntax was required because the colon would confuse FreeMarker |
| otherwise.)</p> |
| |
| <p>As the value of <code class="inline-code">ns_prefixes</code> is a hash, you |
| can register multiple prefixes:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-template"><#ftl ns_prefixes={ |
| "e":"http://example.com/ebook", |
| "f":"http://example.com/form", |
| "vg":"http://example.com/vectorGraphics"} |
| ></pre></div> |
| |
| <p>The <code class="inline-code">ns_prefixes</code> parameter affects the whole |
| <a href="dgui_misc_namespace.html">FTL namespace</a>. This means |
| in practice that the prefixes you have registered in the main page |
| template will be visible in all <code class="inline-code"><#include |
| ...></code>-d templates, but not in <code class="inline-code"><#imported |
| ...></code>-d templates (often referred as FTL libraries). Or |
| from another point of view, an FTL library can register XML |
| namespace prefixes for it's own use, without interfering with the |
| prefix registrations of the main template and other |
| libraries.</p> |
| |
| <p>Note that, if an input document is dominated by a given XML |
| namespace, you can set that as the default namespace for |
| convenience. This means that if you don't use prefix, as in |
| <code class="inline-code">doc.book</code>, then it selects element that belongs to |
| the default namespace. The setting of the default namespace happens |
| with reserved prefix <code class="inline-code">D</code>, for example:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-template"><#ftl ns_prefixes={"D":"http://example.com/ebook"}></pre></div> |
| |
| <p>Now expression <code class="inline-code">doc.book</code> select the |
| <code class="inline-code">book</code> element that belongs to XML namespace |
| <code class="inline-code">http://example.com/ebook</code>. Unfortunately, XPath |
| does not support this idea of a default namespace. Thus, in XPath |
| expressions, element names without prefixes always select the |
| elements that does not belong to any XML namespace. However, to |
| access elements in the default namespace you can directly use prefix |
| <code class="inline-code">D</code>, for example: |
| <code class="inline-code">doc["D:book/D:chapter[title='Ch1']"]</code>.</p> |
| |
| <p>Note that when you use a default namespace, then you can |
| select elements that does not belong to any node namespace with |
| reserved prefix <code class="inline-code">N</code>, for example |
| <code class="inline-code">doc.book["N:foo"]</code>. It doesn't go for XPath |
| expressions, where the above can be witten as |
| <code class="inline-code">doc["D:book/foo"]</code>.</p> |
| |
| |
| |
| |
| |
| <h2 class="content-header header-section2" id="autoid_73">Don't forget escaping!</h2> |
| |
| |
| <p>We have made a big mistake in all examples. We generate output |
| of HTML format, and HTML format reserves characters as |
| <code class="inline-code"><</code>, <code class="inline-code">&</code>, etc. So when we |
| print plain text (as the titles and paragraphs), we have to escape |
| it. Thus, the correct version of the example is:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-template"><strong><#escape x as x?html></strong> |
| <#assign book = doc.book> |
| <h1>${book.title}</h1> |
| <#list book.chapter as ch> |
| <h2>${ch.title}</h2> |
| <#list ch.para as p> |
| <p>${p} |
| </#list> |
| </#list> |
| <strong></#escape></strong></pre></div> |
| |
| <p>So if the book title is "Romeo & Julia", the resulting |
| HTML output will be correctly:</p> |
| |
| |
| |
| <div class="code-wrapper"><pre class="code-block code-output"><em>...</em> |
| <h1>Romeo &amp; Julia</h1> |
| <em>...</em></pre></div> |
| <div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="xgui_imperative.html"><span>Previous</span></a><a class="paging-arrow next" href="xgui_imperative_formal.html"><span>Next</span></a></div></div></div></div> </div> |
| </div> |
| <div class="site-footer"><div class="site-width"><div class="footer-bottom"> <p class="last-generated"> |
| Last generated: |
| <time itemprop="dateModified" datetime="2020-07-09T23:48:37Z" title="Thursday, July 9, 2020 11:48:37 PM GMT">2020-07-09 23:48:37 GMT</time> </p> |
| <p class="copyright"> |
| © <span itemprop="copyrightYear">1999</span>–2020 |
| <a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p> |
| </div></div></div></body> |
| </html> |