http-request as a filter

I've written many components that act as a filter and only act upon particular
named elements.  While this is  a shorthand for something like:

<p:viewport name="filter" match="c:http-request">
...
<p:http-request name="action"> ...</p:http-request>

</p:viewport>

I'd like to consider certain steps as "filters".

A filter is a step that acts upon certain named elements.  It applies itself
to all instances of that element in the input document.  If there are nested
elements, the step must say how it acts.

For example, the p:http-request step could act upon all all outer
c:http-request elements found in the document rather than expect just the
document element to be a c:http-request element.

This allows this kind of pipeline to work:

<p:pipeline name="index"
        xmlns:p='http://www.w3.org/2007/03/xproc'
xmlns:c="http://www.w3.org/2007/03/xproc-step"
        xmlns:atom="http://www.w3.org/2005/Atom">
   <p:input port="pipe-input"/>
   <p:output port="pipe-output">
      <p:pipe step="links" port="final"/>
   </p:output>

   <p:identity name="metadata">
      <p:input port="source">
         <p:inline>
            <c:http-request method="get"
              href="http://localhost:8080/M/" username="admin"
password="admin"/>
         </p:inline>
      </p:input>
   </p:identity>

   <p:http-request name="request-metadata">
      <p:input port="source">
         <p:pipe step="metadata" port="result"/>
      </p:input>
   </p:http-request>

   <p:viewport name="links" match="/atom:feed/atom:link">
      <p:viewport-source>
         <p:pipe step="request-metadata" port="result"/>
      </p:viewport-source>
      <p:output port="final">
         <p:pipe step="request-feed" port="result"/>
      </p:output>

      <p:xslt name="make-request">
         <p:input port="source">
            <p:pipe step="links" port="current"/>
         </p:input>
         <p:input port="transform">
            <p:inline>
               <xsl:transform
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
               <xsl:output method="xml"/>

               <xsl:template match="atom:link[@rel='related']">
                  <c:http-request method="get"  href="{@href}"
username="admin" password="admin"/>
               </xsl:template>

               <xsl:template match="node()|@*">
                  <xsl:copy>
                     <xsl:apply-templates select="@*|node()"/>
                  </xsl:copy>
               </xsl:template>

               </xsl:transform>
            </p:inline>
         </p:input>
      </p:xslt>

      <p:http-request name="request-feed">
         <p:input port="source">
            <p:pipe step="make-request" port="result"/>
         </p:input>
      </p:http-request>

   </p:viewport>

</p:pipeline>

The above pipeline receives an atom feed and then transforms one of
the atom:link elements
into a c:http-request element.  That is then processed by the
p:http-request step.  If the
p:http-request step doesn't see a c:http-request element, it acts as identity.

If we didn't allow p:http-request to acts as a filter, I'd have to do:

<p:pipeline name="index"
        xmlns:p='http://www.w3.org/2007/03/xproc'
xmlns:c="http://www.w3.org/2007/03/xproc-step"
        xmlns:atom="http://www.w3.org/2005/Atom">
   <p:input port="pipe-input"/>
   <p:output port="pipe-output">
      <p:pipe step="links" port="final"/>
   </p:output>

   <p:identity name="metadata">
      <p:input port="source">
         <p:inline>
            <c:http-request method="get"
              href="http://localhost:8080/M/" username="admin"
password="admin"/>
         </p:inline>
      </p:input>
   </p:identity>

   <p:http-request name="request-metadata">
      <p:input port="source">
         <p:pipe step="metadata" port="result"/>
      </p:input>
   </p:http-request>

   <p:viewport name="links" match="/atom:feed/atom:link">
      <p:viewport-source>
         <p:pipe step="request-metadata" port="result"/>
      </p:viewport-source>
      <p:output port="final">
         <p:pipe step="request-feed" port="result"/>
      </p:output>

      <p:xslt name="make-request">
         <p:input port="source">
            <p:pipe step="links" port="current"/>
         </p:input>
         <p:input port="transform">
            <p:inline>
               <xsl:transform
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
               <xsl:output method="xml"/>

               <xsl:template match="atom:link[@rel='related']">
                  <c:http-request method="get"  href="{@href}"
username="admin" password="admin"/>
               </xsl:template>

               <xsl:template match="node()|@*">
                  <xsl:copy>
                     <xsl:apply-templates select="@*|node()"/>
                  </xsl:copy>
               </xsl:template>

               </xsl:transform>
            </p:inline>
         </p:input>
      </p:xslt>


    <p:viewport name="requests" match="c:http-request">
      <p:viewport-source>
         <p:pipe step="make-request" port="result"/>
      </p:viewport-source>
      <p:output port="final">
         <p:pipe step="request-feed" port="result"/>
      </p:output>
        <p:http-request name="request-feed">
         <p:input port="source">
            <p:pipe step="requests" port="current"/>
         </p:input>
      </p:http-request>
    </p:viewport>

   </p:viewport>

</p:pipeline>

That extra viewport is somewhat annoying.

In the end, anyone can write a step that acts as a filter.  The
question I'm asking is
whether or not we want some of our steps in our library to act as
filters and remove
the need for wrapping things in viewports in this common situation.

-- 
--Alex Milowski
"The excellence of grammar as a guide is proportional to the paucity of the
inflexions, i.e. to the degree of analysis effected by the language
considered."

Bertrand Russell in a footnote of Principles of Mathematics

Received on Wednesday, 27 June 2007 16:13:24 UTC