Basics  
    
    
    
    
   Note
          This section uses the DOM tree and the variable made in the
          previous chapter.
         
Assume that the programmer has put the XML document into the
        data-model as variable doc. This variable
        corresponds to the root of the DOM
        tree, the ``document''. The actual variable structure behind
        doc 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.
            
  
  
  
  
Accessing elements by name  
          This FTL prints the title of the book:
            |   |   | 
  | 
<h1>${doc.book.title}</h1>   |  
  |   | 
  |   |   |       
   
          The output will be:
          
          As you see, both doc and
          book can be used as hashes; you get their child
          nodes as subvariables. Basically, you describe the path by which you
          reach the target (element title) in the DOM tree.
          You may notice that there was some swindle above: with
          ${doc.book.title}, it seems that we instruct
          FreeMarker to print the title element itself, but
          we should print its child text node (check the DOM tree). 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 ${doc.book} would stop with
          error.
          This FTL prints the titles of the two chapters:
            |   |   | 
  | 
<h2>${doc.book.chapter[0].title}</h2>
<h2>${doc.book.chapter[1].title}</h2>   |  
  |   | 
  |   |   |       
   
          Here, as book has 2
          chapter element children,
          doc.book.chapter is a sequence that stores the
          two element nodes. Thus, we can generalize the above FTL, so it
          works with any number of chapters:
            |   |   | 
  | 
<#list doc.book.chapter as ch>
  <h2>${ch.title}</h2>
</#list>   |  
  |   | 
  |   |   |       
   
          But what's if there is only one chapter? Actually, when you
          access an element as hash subvariable, it is
          always 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:
            |   |   | 
  | 
<h1>${doc.book[0].title[0]}</h1>   |  
  |   | 
  |   |   |       
   
          But you know that there is exactly 1 book
          element, and that a book has exactly 1 title, so you can omit the
          [0]-s.
          ${doc.book.chapter.title} would work too, if the
          book happen to have only 1 chapter-s (otherwise
          it is ambiguous: how is it to know if the title
          of which chapter 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 book has no
          chapter child, then
          doc.book.chapter will be a 0 length sequence, so
          the FTL with <#list ...> will still
          work.
          It is important to realize the consequence that, for example,
          if book has no chapter-s then
          book.chapter is an empty sequence, so
          doc.book.chapter?? will not
          be false, it will be always
          true! Similarly,
          doc.book.somethingTotallyNonsense?? will not be
          false either. To check if there was no children
          found, use doc.book.chapter[0]?? (or
          doc.book.chapter?size == 0). Of course you can
          use similarly all the missing value handler
          operators (e.g.
          doc.book.author[0]!"Anonymous"), just don't
          forget that [0].
          
   Note
            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.
           
          Now we finish the example by printing all the
          para-s of each chapter:
            |   |   | 
  | 
<h1>${doc.book.title}</h1>
<#list doc.book.chapter as ch>
  <h2>${ch.title}</h2>
  <#list ch.para as p>
    <p>${p}
  </#list>
</#list>   |  
  |   | 
  |   |   |       
   
          this will print:
            |   |   | 
  | 
<h1>Test</h1>
  <h2>Ch1</h2>
    <p>p1.1
    <p>p1.2
    <p>p1.3
  <h2>Ch2</h2>
    <p>p2.1
    <p>p2.2   |  
  |   | 
  |   |   |       
   
          The above FTL could be written more nicely as:
            |   |   | 
  | 
<#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>   |  
  |   | 
  |   |   |       
   
          Finally, a ``generalized`` usage of the child selector
          mechanism: this template lists all para-s of the
          example XML document:
            |   |   | 
  | 
<#list doc.book.chapter.para as p>
  <p>${p}
</#list>   |  
  |   | 
  |   |   |       
   
          The output will be:
            |   |   | 
  | 
  <p>p1.1
  <p>p1.2
  <p>p1.3
  <p>p2.1
  <p>p2.2
      |  
  |   | 
  |   |   |       
   
          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
          chapter returns a sequence of size 2 (since there
          are two chapter-s), and then subvariable
          para selects the para child
          nodes of all nodes in that sequence.
          A negative consequence of this mechanism is that things like
          doc.somethingNonsense.otherNonsesne.totalNonsense
          will just evaluate to an empty sequence, and you don't get any error
          messages.
        
            
  
  
  
  
Accessing attributes  
          This XML is the same as the original, except that it uses
          attributes for the titles, instead of elements:
            |   |   | 
  | 
<!-- 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>   |  
  |   | 
  |   |   |       
   
          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:
            |   |   | 
  | 
<#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>   |  
  |   | 
  |   |   |       
   
          This will print exactly the same as the previous
          example.
          Getting attributes follows the same logic as getting child
          elements, so the result of ch.@title above is a
          sequence of size 1. If there were no title
          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 foo has attribute
          bar then you have to write
          foo.@bar[0]??. (foo.@bar?? is
          wrong, because it always returns true.)
          Similarly, if you want a default value for the
          bar attribute, then you have to write
          foo.@bar[0]!"theDefaultValue".
          As with child elements, you can select the attributes of
          multiple nodes. For example, this template prints the titles of all
          chapters:
            |   |   | 
  | 
<#list doc.book.chapter.@title as t>
  ${t}
</#list>   |  
  |   | 
  |   |   |       
   
        
            
  
  
  
  
Exploring the tree  
          This FTL will enumerate all child nodes of the book
          element:
            |   |   | 
  | 
<#list doc.book?children as c>
- ${c?node_type} <#if c?node_type = 'element'>${c?node_name}</#if>
</#list>   |  
  |   | 
  |   |   |       
   
          this will print:
            |   |   | 
  | 
- text
- element title
- text
- element chapter
- text
- element chapter
- text    |  
  |   | 
  |   |   |       
   
          The meaning of ?node_type is probably clear
          without explanation. There are several node types that can occur in
          a DOM tree, such as "element",
          "text", "comment",
          "pi", ...etc.
          The ?node_name 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 later
          chapter.
          If the book element had attributes, they would
          not appear in the above list, for practical
          reasons. But you can get a list that contains all attributes of the
          element, with subvariable @@ of the element
          variable. If you modify the first line of the XML to this:
            |   |   | 
  | 
<book foo="Foo" bar="Bar" baaz="Baaz">    |  
  |   | 
  |   |   |       
   
          and run this FTL:
            |   |   | 
  | 
<#list doc.book.@@ as attr>
- ${attr?node_name} = ${attr}
</#list>   |  
  |   | 
  |   |   |       
   
          then you get this output (or something similar):
            |   |   | 
  | 
- baaz = Baaz
- bar = Bar
- foo = Foo    |  
  |   | 
  |   |   |       
   
          Returning to the listing of children, there is a convenience
          subvariable to list only the element children of an element:
            |   |   | 
  | 
<#list doc.book.* as c>
- ${c?node_name}
</#list>   |  
  |   | 
  |   |   |       
   
          This will print:
            |   |   | 
  | 
- title
- chapter
- chapter    |  
  |   | 
  |   |   |       
   
          You get the parent of an element with the
          parent built-in:
            |   |   | 
  | 
<#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}   |  
  |   | 
  |   |   |       
   
          This will print:
            |   |   | 
  | 
para
chapter
book
@document    |  
  |   | 
  |   |   |       
   
          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.
          You can quickly go back to the document node using the
          root built-in:
            |   |   | 
  | 
<#assign e = doc.book.chapter[0].para[0]>
${e?root?node_name}
${e?root.book.title}   |  
  |   | 
  |   |   |       
   
          This will print:
          
          For the complete list of built-ins you can use to navigate in
          the DOM tree, read the reference
          of node built-ins.
        
            
  
  
  
  
Using XPath expressions  
          
   Note
            XPath expressions work only if Jaxen (recommended, but use
            at least Jaxen 1.1-beta-8, not older) or Apache Xalan
            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.)
           
          
   Note
            Don't use the sample XML from the previous section, where
            title is an attribute; that applies only to
            that section.
           
          If a hash key used with a node variable can't be interpreted
          otherwise (see the next
          section for the precise definition), then it will by
          interpreted as an XPath expression. For more information on XPath,
          please visit http://www.w3.org/TR/xpath.
          For example, here we list the para elements
          of the chapter with title element (not
          attribute!) content "Ch1'':
            |   |   | 
  | 
<#list doc["book/chapter[title='Ch1']/para"] as p>
  <p>${p}
</#list>   |  
  |   | 
  |   |   |       
   
          It will print:
          
          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'':
            |   |   | 
  | 
${doc["book/chapter[title='Ch1']/para[1]"]}   |  
  |   | 
  |   |   |       
   
          which prints the same as:
            |   |   | 
  | 
${doc["book/chapter[title='Ch1']/para[1]"][0]}   |  
  |   | 
  |   |   |       
   
          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:
            |   |   | 
  | 
${doc.book["chapter[title='Ch1']/para[1]"]}   |  
  |   | 
  |   |   |       
   
          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.
          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 "/book/chapter[1]", while
          the FTL expression is book.chapter[0].
          If the programmer has set up FreeMarker to use Jaxen instead
          of Xalan, then FreeMarker variables are visible with XPath variable
          references:
            |   |   | 
  | 
<#assign currentTitle = "Ch1">
<#list doc["book/chapter[title=$currentTitle]/para"] as p>
...    |  
  |   | 
  |   |   |       
   
          Note that $currentTitle is not a FreeMarker
          interpolation, as there are no { and
          } there. That's an XPath expression.
          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
          para elements in the XML document, so the result
          is a number:
          
          The output will be:
          
        
            
  
  
  
  
XML namespaces  
          
          Be default, when you write something like
          doc.book, then it will select the element with
          name book 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 book is in XML
          namespace http://example.com/ebook, then you have
          to associate a prefix with it at the top of the template with the
          ns_prefixes parameter of the ftl
          directive:
            |   |   | 
  | 
<#ftl ns_prefixes={"e":"http://example.com/ebook"}>   |  
  |   | 
  |   |   |       
   
          And now you can write expressions as
          doc["e:book"]. (The usage of square bracket
          syntax was required because the colon would confuse FreeMarker
          otherwise.)
          As the value of ns_prefixes is a hash, you
          can register multiple prefixes:
            |   |   | 
  | 
<#ftl ns_prefixes={
    "e":"http://example.com/ebook",
    "f":"http://example.com/form",
    "vg":"http://example.com/vectorGraphics"}
>   |  
  |   | 
  |   |   |       
   
          The ns_prefixes parameter affects the whole
          FTL namespace. This means
          in practice that the prefixes you have registered in the main page
          template will be visible in all <#include
          ...>-d templates, but not in <#imported
          ...>-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.
          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
          doc.book, then it selects element that belongs to
          the default namespace. The setting of the default namespace happens
          with reserved prefix D, for example:
            |   |   | 
  | 
<#ftl ns_prefixes={"D":"http://example.com/ebook"}>   |  
  |   | 
  |   |   |       
   
          Now expression doc.book select the
          book element that belongs to XML namespace
          http://example.com/ebook. 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
          D, for example:
          doc["D:book/D:chapter[title='Ch1']"].
          Note that when you use a default namespace, then you can
          select elements that does not belong to any node namespace with
          reserved prefix N, for example
          doc.book["N:foo"]. It doesn't go for XPath
          expressions, where the above can be witten as
          doc["D:book/foo"].
        
            
  
  
  
  
Don't forget escaping!  
          We have made a big mistake in all examples. We generate output
          of HTML format, and HTML format reserves characters as
          <, &, 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:
            |   |   | 
  | 
<#escape x as x?html>
<#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>
</#escape>   |  
  |   | 
  |   |   |       
   
          So if the book title is "Romeo & Julia", the resulting
          HTML output will be correctly:
            |   |   | 
  | 
...
<h1>Romeo & Julia</h1>
...    |  
  |   | 
  |   |   |