Extending steps

Another one on the subject of XProc enhancements...

On a couple of occasions recently I found myself extending existing pipeline steps like this:

<?xml version="1.0" encoding="UTF-8"?>
<p:library xmlns:c="http://www.w3.org/ns/xproc-step"
    xmlns:p="http://www.w3.org/ns/xproc"
    xmlns:svrl="http://purl.oclc.org/dsdl/svrl"
    xmlns:test="http://www.w3.org/ns/xproc/test"
    version="1.0">

  <p:documentation>Test Library Steps</p:documentation>


  <p:declare-step name="validate-with-schematron" type="test:validate-with-schematron">
    <p:documentation>Extends the standard p:validate-with-schematron step by adding the result handling to return the passed result or the failed test report.</p:documentation>
    <p:input port="source" primary="true"/>
    <p:input port="parameters" kind="parameter"/>
    <p:input port="schema"/>
    <p:output port="result" primary="true"/>
    <p:output port="report" sequence="true"/>
    <p:option name="phase" select="'#ALL'"/>                      <!-- string -->
    <p:option name="assert-valid" select="'true'"/>

    <p:validate-with-schematron name="validate">
      <p:input port="schema">
        <p:pipe port="schema" step="validate-with-schematron"/>
      </p:input>
      <p:input port="parameters">
        <p:pipe port="parameters" step="validate-with-schematron"/>
      </p:input>
      <p:with-option name="phase" select="$phase"/>
      <p:with-option name="assert-valid" select="$assert-valid"/>
    </p:validate-with-schematron>

    <test:result>
      <p:input port="test">
        <p:pipe port="source" step="validate-with-schematron"/>
      </p:input>
      <p:input port="report">
        <p:pipe port="report" step="validate"/>
      </p:input>
    </test:result>
  </p:declare-step>


  <p:declare-step name="result" type="test:result">
    <p:documentation>Returns the SVRL report if the test fails or the test result if the test is successful.</p:documentation>
    <p:input port="source" primary="true"/>
    <p:input port="test" primary="false"/>
    <p:input port="report" primary="false"/>
    <p:output port="result"/>

    <p:sink/>

    <p:choose>
      <p:xpath-context>
        <p:pipe port="report" step="result"/>
      </p:xpath-context>
      <p:when test="exists(/svrl:schematron-output/svrl:failed-assert)">
        <p:identity>
          <p:input port="source">
            <p:pipe port="report" step="result"/>
          </p:input>
        </p:identity>
      </p:when>
      <p:otherwise>
        <p:identity>
          <p:input port="source">
            <p:pipe port="test" step="result"/>
          </p:input>
        </p:identity>
      </p:otherwise>
    </p:choose>
  </p:declare-step>
</p:library>

The intention, in the above example was to encapsulate the additional behavior of returning the result of the test if it passed or the error report if it failed when assert-valid is true. However, from the users perspective they still use the same validate-with-schematron step, all be it in a different namespace.

Now, what I think might be useful is to rather than have to copy-out the entire step declaration for validate-with-schematron (which can be tedious for things like p:http-request) but instead have a mechanism by which we can 'extend' a step declaration, may be like this:

  <p:declare-step" extends="p:validate-with-schematron" type="test:validate-with-schematron"
      name="validate-with-schematron">
    <p:validate-with-schematron name="validate">
      <p:input port="schema">
        <p:pipe port="schema" step="validate-with-schematron"/>
      </p:input>
      <p:input port="parameters">
        <p:pipe port="parameters" step="validate-with-schematron"/>
      </p:input>
      <p:with-option name="phase" select="$phase"/>
      <p:with-option name="assert-valid" select="$assert-valid"/>
    </p:validate-with-schematron>

    <test:result>
      <p:input port="test">
        <p:pipe port="source" step="validate-with-schematron"/>
      </p:input>
      <p:input port="report">
        <p:pipe port="report" step="validate"/>
      </p:input>
    </test:result>
  </p:declare-step>

In this example you can miss-out the input and option declarations and get on with adding the extra bits that matter. You should also be able to additional inputs, outputs and options too. One this to point out here... the use of what also appears to be undeclared option variables e.g. $assert-valid. I don't know how people would feel about doing that along with referencing inputs and outputs that are implied as a result of 'extending' the step.

Please also note, the above examples also illustrate a use case for the #current / #parent pipeline name tokens that I've described previously. Instead of having to name and reference the step declaration explicitly, it would have been a nice 'short-cut' to use #current-declaration (or something like that) instead in the p:pipe instructions.


Regards

Philip

Received on Wednesday, 11 January 2012 09:56:10 UTC