rdftemplate

Library for generating XML documents from RDF data using templates
git clone https://code.djc.id.au/git/rdftemplate/

src/doc/sphinx/xml-template.rst (10213B) - raw

      1 XML templates
      2 =============
      3 
      4 Templates are pure XML, with special directives embedded in the document as 
      5 attributes and elements. Substitutions are also supported inside character data 
      6 and attribute values.
      7 
      8 The template syntax is inspired by the `Genshi`_ templating library for Python.
      9 
     10 .. _Genshi: http://genshi.edgewall.org/
     11 
     12 XML namespace
     13 -------------
     14 
     15 The XML elements and attributes handled by rdftemplate are defined in 
     16 a dedicated namespace:
     17 
     18 .. code-block:: none
     19 
     20     http://code.miskinhill.com.au/rdftemplate/
     21 
     22 By convention this namespace is mapped to the prefix ``rdf``. For example:
     23 
     24 .. code-block:: xml
     25 
     26    <html xmlns="http://www.w3.org/1999/xhtml"
     27          xmlns:rdf="http://code.miskinhill.com.au/rdftemplate/">
     28    ...
     29    </html>    
     30 
     31 All declarations of the rdftemplate namespace are stripped from the resulting 
     32 document when a template is rendered.
     33 
     34 Substitutions in character data and attribute values
     35 ----------------------------------------------------
     36 
     37 Templates may contain substitutions embedded in character data or in attribute 
     38 values. Substitutions are delimited by ``${`` and ``}`` and contain 
     39 a :doc:`selector expression <selector>`, which is evaluated with respect to the 
     40 current context node (passed to the :java:class:`TemplateInterpolator` when 
     41 rendering the template).
     42 
     43 The selector expression must have exactly one result when evaluated. The type 
     44 of the result affects how substitution is performed:
     45 
     46 * If the selector expression evaluates to an
     47   `XML literal node <http://www.w3.org/TR/rdf-concepts/#section-XMLLiteral>`_ 
     48   or an instance of :java:class:`XMLStream <au.id.djc.rdftemplate.XMLStream>`, 
     49   the entire XML tree is inserted into the resulting document. (This 
     50   substitution is only possible in character data; if it occurs in an attribute 
     51   value, an exception will be thrown.)
     52 
     53 * If the selector expression evaluates to any other type of literal node, it 
     54   will be converted to a Java type using Jena’s type conversion facilities, and 
     55   then toString() will be called on the converted object.
     56 
     57 * If any other Java object is encountered, toString() will be called on it. 
     58   This means that when a selector expression evaluates to a :java:class:`String 
     59   <java.lang.String>`, it will be inserted as-is.
     60 
     61 Consider the following example of a template for describing an article in HTML. 
     62 It uses subtitutions in character data and in attribute values:
     63 
     64 .. code-block:: xml
     65 
     66     <html xmlns="http://www.w3.org/1999/xhtml"
     67           xmlns:rdf="http://code.miskinhill.com.au/rdftemplate/">
     68         <head>
     69             <title>${dc:title#string-lv}</title>
     70             <meta name="DC.creator" content="${dc:creator#string-lv}" />
     71         </head>
     72         <body>
     73             <p>Title: ${dc:title}</p>
     74         </body>
     75     </html>
     76 
     77 In this example, the object of ``dc:title`` might be an XML literal containing 
     78 an HTML ``<span>`` element. The ``#string-lv`` :ref:`adaptation <adaptations>` 
     79 is used to strip markup from XML literals in the ``<title>`` element and the 
     80 ``content`` attribute, where markup is not permitted. On the other hand, the 
     81 title’s complete XML tree will be inserted into the ``<p>`` element with all 
     82 markup preserved.
     83 
     84 This example will also work correctly if the object of ``dc:title`` is a plain 
     85 literal rather than an XML literal, since ``#string-lv`` will pass the plain 
     86 literal through untouched.
     87 
     88 Substitutions with ``rdf:content``
     89 ----------------------------------
     90 
     91 The ``rdf:content`` attribute is used to replace an element’s content with the 
     92 result of evaluating a selector expression. The selector expression must have 
     93 exactly one result when evaluated. For example:
     94 
     95 .. code-block:: xml
     96 
     97     <html xmlns="http://www.w3.org/1999/xhtml"
     98           xmlns:rdf="http://code.miskinhill.com.au/rdftemplate/">
     99         <body>
    100             <h1 rdf:content="dc:title" />
    101         </body>
    102     </html>
    103 
    104 The ``rdf:content`` attribute is stripped from the resulting document. The 
    105 substitution rules described above also apply for ``rdf:content`` (so XML 
    106 literals will be inserted as-is into the resulting document), with one minor 
    107 enhancement: if the selector expression evaluates to a literal node with 
    108 a language tag, that language will be set on the enclosing element in an 
    109 `xml:lang <http://www.w3.org/TR/REC-xml/#sec-lang-tag>`_ attribute (and also an 
    110 XHTML ``lang`` attribute, if the document uses the XHTML namespace).
    111 
    112 If the object of the ``dc:title`` property is the literal ``"Война и мир"@ru`` 
    113 in the example above, then the template would be rendered as:
    114 
    115 .. code-block:: xml
    116 
    117     <html xmlns="http://www.w3.org/1999/xhtml">
    118         <body>
    119             <h1 xml:lang="ru" lang="ru">Война и мир</h1>
    120         </body>
    121     </html>
    122 
    123 Note that if the element has any content in the template, this will be 
    124 discarded when rendering.
    125 
    126 Repetition with ``rdf:for``
    127 ---------------------------
    128 
    129 The ``rdf:for`` attribute can be used to loop over zero or more results from 
    130 a selector expression. For each node in the results, the element and its 
    131 subtree will be rendered using that node as the context node. All template 
    132 constructs may be nested inside the subtree, including other ``rdf:for`` loops.
    133 
    134 For example, given the following RDF graph:
    135 
    136 .. include:: example-graph.rst.inc
    137 
    138 the following template could be used to produce an HTML listing of the people 
    139 who are known to a particular person:
    140 
    141 .. code-block:: xml
    142 
    143     <html xmlns="http://www.w3.org/1999/xhtml"
    144           xmlns:rdf="http://code.miskinhill.com.au/rdftemplate/">
    145         <body>
    146             <h1>${foaf:name}’s buddies</h1>
    147             <ul>
    148                 <li rdf:for="foaf:knows(foaf:name)">
    149                     <a href="#uri" rdf:content="foaf:name" />
    150                 </li>
    151             </ul>
    152         </body>
    153     </html>
    154 
    155 If ``<bob>`` is used as the context node, the ``foaf:knows(foaf:name)`` 
    156 expression will select two nodes: ``<alice>`` and ``<carol>``, in that order. 
    157 The ``<li>`` element will therefore be rendered twice, the first time with its 
    158 context node set to ``<alice>``, the second time set to ``<carol>``. The 
    159 resulting XML would be:
    160 
    161 .. code-block:: xml
    162 
    163     <html xmlns="http://www.w3.org/1999/xhtml">
    164         <body>
    165             <h1>Bob’s buddies</h1>
    166             <ul>
    167                 <li><a href="alice">Alice</a></li>
    168                 <li><a href="carol">Carol</a></li>
    169             </ul>
    170         </body>
    171     </html>
    172 
    173 ``rdf:for`` can also be given as an XML element, with its selector expression 
    174 in an attribute named ``each``. This will be rendered in the same way, except 
    175 that the entire ``rdf:for`` element is stripped out. In the example above, 
    176 ``<li rdf:for="foaf:knows(foaf:name)">...</li>`` is equivalent to ``<rdf:for 
    177 each="foaf:knows(foaf:name)"><li>...</li></rdf:for>``.
    178 
    179 Because of the potential for ambiguity, it is illegal to combine ``rdf:for`` 
    180 with other directives on the same element.
    181 
    182 Concatenation with ``rdf:join``
    183 -------------------------------
    184 
    185 The ``rdf:join`` element behaves in the same way as the ``rdf:for`` element, 
    186 but it also accepts a ``separator`` attribute, which specifies a string to be 
    187 inserted between each repetition.
    188 
    189 For example, here is a briefer version of the template above:
    190 
    191 .. code-block:: xml
    192 
    193     <html xmlns="http://www.w3.org/1999/xhtml"
    194           xmlns:rdf="http://code.miskinhill.com.au/rdftemplate/">
    195         <body>
    196             <p>${foaf:name}’s buddies:
    197             <rdf:join each="foaf:knows(foaf:name)" separator=", ">
    198                 <a href="#uri" rdf:content="foaf:name" />
    199             </rdf:join>
    200             </p>
    201         </body>
    202     </html>
    203 
    204 Conditionals with ``rdf:if``
    205 ----------------------------
    206 
    207 The ``rdf:if`` attribute will cause an element and its subtree to be included 
    208 in the resulting document only if the selector expression evaluates to *one or 
    209 more* items. Use a :ref:`predicate <predicates>` in the selector expression to 
    210 express complex conditions. For example:
    211 
    212 .. code-block:: xml
    213 
    214     <html xmlns="http://www.w3.org/1999/xhtml"
    215           xmlns:rdf="http://code.miskinhill.com.au/rdftemplate/">
    216         <body>
    217             <p rdf:if="dc:identifier[uri-prefix='urn:issn:']">
    218                 ISSN: ${dc:identifier#uri-slice(9)}
    219             </p>
    220         </body>
    221     </html>
    222 
    223 When rendering this template, the ``<p>`` element will only be included if 
    224 there is some object of the ``dc:identifier`` property which satisfies the 
    225 ``uri-prefix='urn:issn:'`` predicate.
    226 
    227 There is also an element form of ``rdf:if``. Use the ``test`` attribute to 
    228 specify the selector expression to test against, or the ``not`` attribute to 
    229 apply an inverse test.
    230 
    231 A pair of ``rdf:if`` elements can be used to make a choice between two 
    232 alternatives. For example:
    233 
    234 .. code-block:: xml
    235 
    236     <html xmlns="http://www.w3.org/1999/xhtml"
    237           xmlns:rdf="http://code.miskinhill.com.au/rdftemplate/">
    238         <body>
    239             <p>
    240                 <rdf:if test="ex:thumbnail"><img src="${ex:thumbnail#uri}" /></rdf:if>
    241                 <rdf:if not="ex:thumbnail">No thumbnail available :-(</rdf:if>
    242             </p>
    243         </body>
    244     </html>
    245 
    246 Rendering templates
    247 -------------------
    248 
    249 .. java:class:: au.id.djc.rdftemplate.TemplateInterpolator
    250 
    251    Use this class to render templates. Instances of this class can safely be 
    252    shared across threads (for example, as singleton beans in Spring).
    253 
    254    .. java:method:: TemplateInterpolator(au.id.djc.rdftemplate.selector.SelectorFactory selectorFactory)
    255 
    256       The given :java:class:`SelectorFactory 
    257       <au.id.djc.rdftemplate.selector.SelectorFactory>` will be used to 
    258       evaluate selector expressions when rendering templates.
    259 
    260    .. java:method:: java.lang.String interpolate(java.io.Reader reader, com.hp.hpl.jena.rdf.model.RDFNode node)
    261 
    262       Reads a template from the given :java:class:`Reader <java.io.Reader>`, 
    263       and renders it using the given node as context. The resulting XML 
    264       document is returned.
    265 
    266       A number of overrides of this method also exist for advanced use cases. 
    267       Refer to the `Javadoc for TemplateInterpolator 
    268       <http://code.djc.id.au/rdftemplate/javadoc/latest/au/id/djc/rdftemplate/TemplateInterpolator.html>`_ 
    269       for more details.