Exposing an XML Document to a Template

The class freemarker.ext.jdom.NodeListModel provides a template model for wrapping XML documents represented as JDOM XML 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:

TemplateScalarModel

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.

TemplateCollectionModel

When used as a collection in a <list> expression, it will simply enumerate its nodes. Every node will be returned as a new node list consisting of a single node.

TemplateSequenceModel

When used as a sequence, it will return the i-th node as a new node list consisting of the single requested node.

TemplateHashModel

When used as a hash, it is basically used to traverse children. That is, if you have a node list named "book" that wraps an element node with several chapters, then the book.chapter will yield a node list with all chapter elements of that book element. The at sign is used to refer to attributes: book["@title"] yields a node list with a single attribute node, that is the title attribute of the book element. Note that we had to use the dynamic key syntax since FreeMarker currently does not allow the use of at sign in a name of the key on the right hand side of the dot operator.

The hash defines several "magic keys" as well. All these keys start with an underscore. The most notable is the "_text" key which retrieves the text of the node: ${book["@title"]._text} will render the value of the attribute into the template. Similarly, "_name" will retrieve the name of the element or attribute. "*" or "_allChildren" returns all direct children elements of all elements in the node list, while "@*" or "_allAttributes" returns all attributes of the elements in the node list. There are many more such keys; for detailed description of them please refer to the JavaDoc of the get(String) method of the NodeListModel.

TemplateMethodModel

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 werken.xpath library in your classpath.

Namespace handling

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

public void registerNamespace(String prefix, String uri);
        

method, or inside a template using the

${nodelist._registerNamespace(prefix, uri)}
	

syntax. From there on, you can refer to children elements in the namespace denoted by the particular URI through the syntax

nodelist["prefix:localName"] and nodelist["@prefix:localName"]
	

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.