Simplified template element notes

Notes from our simplified element discussion. These will be incorporated
into the minutes, but in the meantime...

The WG discussed the problem of a "simplified template" step,
something that would make it easier to construct documents with
dynamically generated content.

There seem to be two paths: a clean-slate design targetted at XProc
V.next where we can change the semantics of pipelines in any way we
want, or a design that would be valid in XProc 1.0. Although the
former might produce the best results, for the short and medium term,
it seemed wise to consider what we could accomplish within the
constraints of XProc 1.0.

After much discussion, the WG concluded that we could achieve
significant simplification with two new XProc atomic steps:
p:in-scope-names and p:document-template.

<p:in-scope-names>
  <p:output port="result" primary="false"/>
</p:in-scope-names>

The p:in-scope-names step is roughly analagous to the p:parameters
step. It creates a c:param-set document containing one c:param element
for each in-scope variable and option. The order of the c:param
elements is implementation-dependent.

<p:document-template>
  <p:input port="source"/>
  <p:input port="context" sequence="true"/>
  <p:input port="parameters" kind="parameters"/>
</p:document-template>

The p:document-template step makes a verbatim copy of its source input
with one exception: within attribute values and element content, every
expression delimited by curly braces is treated as an XPath expression
and replaced by the result of evaluating that expression.

* The context item used during evaluation of the expression is the
  document that appears on the context port. It is a dynamic error
  err:XDxxxx if more than one document appears on the context port.

  In an XPath 1.0 implementation, if p:empty is given or implied as
  the context, an empty document node is used as the context node. In
  an XPath 2.0 implementation, the context item is undefined. It is a
  dynamic error (err:XD0026) if the select expression makes reference
  to the context node, size, or position when the context item is
  undefined."

* The names of all the parameters passed to the step are available as
  variable names during expression evaluation.

* If an expression selects one or more nodes from the context, a copy
  of those nodes is inserted in the result document, unless the
  expression occurs in an attribute value in which case their string
  value is used.

* The sequence "{{" is replaced by a single, literal "{".

* The sequence "}}" is replaced by a single, literal "}".

* The version of XPath supported by the step is
  implementation-defined.

Suppose you wish to construct the following document:

  <c:request method="POST" href="http://example.com/post"
             username="user" password="password">
    <c:body>
      <h:div>...</h:div>
    </c:body>
  </c:request>

Where the method, href, username, and password are computed by the
pipeline as either options or variables and the body of the post is
selected from one of the pipeline's input documents (say
/h:html/h:body/h:div[3]).

Using only XProc 1.0 standard steps, this can be accomplished with
several successive p:add-attribute steps and a p:insert step. (There
may be other ways as well, though they are all a bit tedious.)

Using these new steps, it's much simpler:

  <p:in-scope-names name="vars"/>

  <p:document-template>
    <p:input port="source">
      <p:inline>
        <c:request method="{$method}" href="{$uri}"
                   username="{$user}" password="{$password}">
          <c:body>
            { /h:html/h:body/h:div[3] }
          </c:body>
        </c:request>
      </p:inline
    </p:input>
    <p:input port="context" sequence="true">
      <p:pipe step="main" port="result"/>
    </p:input>
    <p:input port="parameters">
      <p:pipe step="vars" port="result"/>
    </p:input>
  </p:document-template>

This is in many ways like a simplified stylesheet in XSLT. In fact,
aside from the new semantics associated with curly-braces in element
content, it could be implemented in XSLT. Conversely, it could be
implemented in XQuery, if you were willing or able to escape all of
the markup and pass it to the p:xquery step in a c:query element.


                                        Be seeing you,
                                          norm

-- 
Norman Walsh
Lead Engineer
MarkLogic Corporation
www.marklogic.com

Received on Thursday, 4 November 2010 13:18:56 UTC