Re: option scope question

Thanks, Norm.  I understood that you have to use p:with-option to
supply dynamic values for options that take strings and booleans and
the like, but I was under the (mistaken) impression that for options
of type XPathExpression, the container step's options are in-scope, as
they are for p:variable and the like.  In other words, that an
XPathExpression is evaluated in the context environment _surrounding_
the step, and not the context _inside_ the step.

I think I got the idea from (1) taking the parallel between
<p:with-option>s and XSLT attribute value templates too far, and (2)
from from 3.2 of the spec: "The scope of option and variable names is
determined by where they are declared. When an option is declared with
p:option (or a variable with p:variable), unless otherwise specified,
its scope consists of the sibling elements that follow its declaration
and the descendants of those siblings."  Since the p:string-replace
was a following sibling of p:option, I assumed the options were in
scope.

Of course, now that I've done a bit more research, I also see 2.6.2.2,
that says when a step evaluates an XPath expression, the context does
not include any variables, unless otherwise specified by the step
itself.  Makes sense, but it's a potential gotcha that that @select
attributes appear to behave differently on step elements than they do
on non-step elements.  (Well, maybe I'm the only one that's been
gotten.)

So, if I understand things correctly, the lesson is:  To pass a
dynamically-constructed value to any step option, you must use
p:with-option.  Step options with type XPathExpression behave no
differently than options of any other type.

Thanks,

-James






On Mon, Jun 29, 2009 at 7:26 AM, Norman Walsh<ndw@nwalsh.com> wrote:
> James Sulak <jsulak@gmail.com> writes:
>> Is this a bug, or am I missing something?
>>
>> <p:declare-step xmlns:p="http://www.w3.org/ns/xproc">
>>
>>   <p:output port="result" primary="true"/>
>>
>>   <p:option name="foo" select="'data'"/>
>>
>>   <p:identity>
>>     <p:input port="source">
>>       <p:inline>
>>         <root>This is some text.</root>
>>       </p:inline>
>>     </p:input>
>>   </p:identity>
>>
>>   <p:string-replace match="root//text()" replace="replace(., 'text', $foo)"/>
>
> The way you've written it, you're asking the p:string-replace step to
> evaluate the string-replace. That won't work because the variables aren't
> in-scope inside the step. You want this:
>
>  <p:string-replace match="root//text()"
>    <p:with-option name="replace"
>                   select="concat('replace(., &quot;text&quot;, '", $foo, "')")/>
>
> Now the XProc processor expands teh value of $foo and passes it to
> string-replace.
>
> A bit ugly, but...
>
>                                        Be seeing you,
>                                          norm
>
> --
> Norman Walsh <ndw@nwalsh.com> | The first step towards wisdom is
> http://nwalsh.com/            | calling things by their right
>                              | names.--Chinese Proverb
>

Received on Monday, 29 June 2009 16:03:38 UTC