Re: Initialize a variable with a parameter port

On 21 November 2011 20:56, Norman Walsh wrote:
> Florent Georges writes:

  Hi,

>>   I try to get a parameter value in a variable, by connecting
>> the variable context to a prameters port and using an
>> expression like "/c:param-set/c:param[...]/@value".  But
>> Calabash gives me the following error:

>>     err:XD0008 : More than one document in context for
>>     parameter 'first' It is a dynamic error if a document
>>     sequence appears where a document to be used as the
>>     context node is expected.

> Hmm. Given that there's only one parameter, I'm surprised that
> doesn't work. But in the general case, what appears on the
> parameters input port is a sequence so that approach isn't
> going to work reliably anyway.

  Yes, I was more reporting the error as I found it than looking
for a solution.  On the other hand, this is quite tedious, to get
the value of a parameter, and should probably be added to
http://w3.org/wiki/XprocVnext ?

> Longer term, maybe there should be a p:parameter() *function*
> that takes the name of an in-scope parameter and returns its
> value.  Pushing the parameters into a document in order to read
> the value back out of the document does seem like going around
> the houses.

  Yes, I think so.  A function would be very helpful, or maybe
more declaratively a special form p:param, which declares a new
variable binding in scope, initialized with a parameter from a
parameter port (by default the primary one if any), with the
same name:

    <!-- declares $foo in scope, with the value of the parameter
         'foo' on the parameter port my-params -->
    <p:param name="foo" port="my-params"/>

  Parameters are different than options by the way the flow
between steps, but within one step, usually I want to refer to
them by name, like any variable (options are more first-class
objects than parameters in that regard).

  Interestingly, this could even be implemented by a phase of
pre-compilation.  Either by a dedicated language providing the
p:param construct and maybe others, or by a generic defmacro
mechanism, more like in LISP:

    <x:defmacro name="my:param" kind="scoped">
       <x:param name="name"/>
       <x:param name="port"/>
       <util:normalize-parameters>
          <x:with-option name="port" select="$port"/>
       </util:normalize-parameters>
       <p:group>
          <p:variable>
             <x:with-option name="name"   select="$name"/>
             <x:with-option name="select" select="
                 concat(
                   '/c:param-set/c:param[@name eq ''',
                   $name,
                   ''']/@value')"/>
          </p:variable>
          <x:scope/>
       </p:group>
    </x:defmacro>

which would pre-compile:

    <my:param name="some-param" port="my-port"/>
    ...

into:

    <util:normalize-parameters port="my-port"/>
    <p:group>
       <p:variable name="some-param" select="
           /c:param-set/c:param[@name eq 'some-param']/@value"/>
       ...
    </p:group>

  I wonder in what use cases this could be interesting in XSLT
too...  But it is now way out of the initial context of this
thread :-)

  Regards,

-- 
Florent Georges
http://fgeorges.org/
http://h2oconsulting.be/

Received on Tuesday, 22 November 2011 00:12:36 UTC