Multiple Outputs from XSLT and Sequence Splitting

Problem: A user uses a stylesheet that produces more than one result
          document.  What is the output of an XSLT step?

I think the simplest answer is that you get a sequence of documents
from that step.

The problem is now that you may want to do different things with
different documents from the sequence from the XSLT transform.  We
can solve this with group by using a component that creates a
subsequence from a sequence of documents based on an XPath expresison:

<p:group name="route">
    <p:declare-input port="sequence" source="transform!result"/>
    <p:declare-output port="articles" source="select-artciles!result"/>
    <p:declare-output port="htmldocs" source="select-htmldocs!result"/>
    <p:declare-output port="otherdocs" source="select-otherdocs!result"/>
    <p:step name="select-articles" component="p:match-sequence">
       <p:input port="sequence" source="route!sequence"/>
       <p:parameter name="expression" value="/article"/>
    </p:step>
    <p:step name="select-htmldocs" component="p:match-sequence">
       <p:input port="sequence" source="route!sequence"/>
       <p:parameter name="expression" value="/h:html"/>
    </p:step>
    <p:step name="select-others" component="p:match-sequence">
       <p:input port="sequence" source="route!sequence"/>
       <p:parameter name="expression" value="not(/h:html|/article)"/>
    </p:step>
</p:group>

The component declaration for [p:]match-sequence is:

<p:declare-component name="p:match-sequence">
    <p:declare-input name="sequence" sequence="yes"/>
    <p:declare-output name="result"/>
    <p:declare-parameter name="expresion" required="true"/>
</p:declare-component>

The one bad part about this solution is that the sequence of
documents must be sent to three places--which greatly increase the
overhead.  Since splitting a sequence of documents into multiple parts
is probably a basic construct, we should probably have some
language construct to support it:

<p:split-sequence name="route">
    <p:declare-input port="sequence" source="transform!result"/>
    <p:declare-output port="articles" source="select-artciles!result"/>
    <p:declare-output port="htmldocs" source="select-htmldocs!result"/>
    <p:declare-output port="otherdocs" source="select-otherdocs!result"/>
    <p:map select="/article" to="articles"/>
    <p:map select="/h:html" to="htmldocs"/>
    <p:map to="otherdocs"/>
</p:split-sequence>

This would have the nice properties that:

   * It is just a step container with no contained steps.
   * It can be implemented in a naive way with group and a component.
   * It can be optimized
   * A clear set of precedence rules (e.g. match in document order)
     can be specified for to which sequence the document is sent.

-- 
--Alex Milowski

Received on Saturday, 9 September 2006 21:34:03 UTC