RE: Reading ports from XPath functions

A possible solution might be introducing a new way to create variables, using something like this:

<p:pipevar name="var" step="..." port="..."/>
or
<p:variable name="var" step="..." port="..."/>

That way we can still build the dependency graph without having to analyze XPath expressions, and you can refer to the content appearing on the port through $var.

To keep the dependency on the output port more local, perhaps a better approach would be to allow this inside p:with-option, p:with-param, p:variable etc.:

<p:with-option name="opt" select="empty($var)">
  <p:pipevar name="var" step="..." port="..."/>
</p:with-option>

or maybe

<p:with-option name="opt" select="empty($var)">
  <p:pipe bind-as="var" step="..." port="..."/>
</p:with-option>

The above are just some immediate ad-hoc ideas, but the idea should be clear.

Vojtech


--
Vojtech Toman
Consultant Software Engineer
EMC | Information Intelligence Group
vojtech.toman@emc.com
http://developer.emc.com/xmltech

> -----Original Message-----
> From: Romain Deltour [mailto:rdeltour@gmail.com]
> Sent: Saturday, February 09, 2013 4:24 PM
> To: xproc-dev@w3.org Dev
> Subject: Re: Reading ports from XPath functions
> 
> Thanks for the thoughts Norm, very clear explanation of the impact on
> the model and implementations.
> 
> Limiting it to static step and port names sounds reasonable. Perhaps it
> could be helpful to statically declare the accessed ports somewhere in
> the XPorc model (e.g. in the p:xpath-context); implems wouldn't have to
> statically parse the XPath, and could fail with a dynamic error if the
> declaration of intent is not right.
> 
> Anyway, as an example, one use case that comes to mind is a p:choose
> depending on the number of docs appearing on a sequence port:
> 
> <?xml version="1.0"?>
> <p:declare-step xmlns:p="http://www.w3.org/ns/xproc" name="main"
> version="1.0">
>   <p:input port="source" sequence="true"/>
>   <!-- Count if there are some docs -->
>   <p:count name="count" limit="1">
>     <p:input port="source">
>       <p:pipe step="main" port="source"/>
>     </p:input>
>   </p:count>
>   <p:sink/>
>   <!--Repipe the primary source port-->
>   <p:identity>
>     <p:input port="source">
>       <p:pipe port="source" step="main"/>
>     </p:input>
>   </p:identity>
>   <p:choose>
>     <p:xpath-context>
>       <p:pipe port="result" step="count"/>
>     </p:xpath-context>
>     <p:when test="/c:result = '0'">
>       ...
>     </p:when>
>     <p:otherwise>
>       ...
>     </p:otherwise>
>   </p:choose>
> </p:declare-step>
> 
> 
> Would be easier done with:
> 
> <?xml version="1.0"?>
> <p:declare-step xmlns:p="http://www.w3.org/ns/xproc" name="main"
> version="1.0">
>   <p:input port="source" sequence="true"/>
>   <p:choose>
>     <p:when test="empty(p:read-port('some-step', 'result'))">
>       ...
>     </p:when>
>     <p:otherwise>
>       ...
>     </p:otherwise>
>   </p:choose>
> </p:declare-step>
> 
> Romain.
> 
> On 9 févr. 2013, at 15:20, Norman Walsh <ndw@nwalsh.com> wrote:
> 
> > Hello world,
> >
> > At XML Prague, both yesterday in the XProcathon and today in Romain
> > Deltour's excellent presentation[1], the suggestion was made that it
> > would be nice to be able to read ports from XPath expressions. I
> > imagine we're talking about something like this:
> >
> >  <px:some-step name="somename">...</px:some-step>
> >
> >  <p:xslt>
> >    ...
> >    <p:with-param name="someParam" select="p:read-port('some-step',
> > 'result')/x/y"/>  </p:xslt>
> >
> > I can certainly see the appeal, but it's worth pointing out that this
> > complicates the data flow analysis that an XProc processor must
> > perform.
> >
> > Today, the processor can look at the port connections and build the
> > entire flow graph. With an extension function that can read from
> > ports, it would be necessary to parse all the XPath expressions in
> > order to find the connections. That's not too burdensome, but it is
> > certainly some burden.
> >
> > And, of course, as soon as you can do p:read-port('some-step',
> > 'result'), someone is going to ask for p:read-port($step, $port) and
> > that's a whole new can of worms to consider.
> >
> > (I believe we would *have* to impose the restriction that $step and
> > $port could be resolved statically, but that wouldn't make users
> > happy.)
> >
> > If you only want to read from *one* port, I think you can always get
> > the results you want:
> >
> >  <p:xslt>
> >    ...
> >    <p:with-param name="someParam" select="/x/y">
> >      <p:pipe step="somename" port="result"/>
> >    </p:with-param>
> >  </p:xslt>
> >
> > But suppose you want to work with the output of two ports:
> >
> >  <p:xslt>
> >    ...
> >    <p:with-param name="booleanParam"
> >                  select="p:read-port('a','b')/root >
> > p:read-port('c','d')"/>  </p:xslt>
> >
> > Then, you've got to work harder:
> >
> >  <p:variable name="aroot" select="/root">
> >    <p:pipe step="a" port="b"/>
> >  </p:variable>
> >
> >  <p:variable name="croot" select="/root">
> >    <p:pipe step="c" port="d"/>
> >  </p:variable>
> >
> >  <p:xslt>
> >    ...
> >    <p:with-param name="booleanParam" select="$aroot > $croot"/>
> > </p:xslt>
> >
> > (Which may involve introducing a new group, but that's a different
> > problem.)
> >
> > In short: adding p:read-port wouldn't introduce any new
> functionality,
> > it would be a convenience. It would have to have some limitations
> that
> > users probably wouldn't expect. On the whole, I can't decide if the
> > (perhaps significant) additional implementation complexity is worth
> it[2].
> >
> > [1] http://www.xmlprague.cz/sessions/#xprocebook
> > [2] "Implementation isn't the user's problem, that's why we pay
> programmers."
> >
> >                                        Be seeing you,
> >                                          norm
> >
> > P.S. Lots of XProc love at XML Prague. Yay!
> >
> > --
> > Norman Walsh
> > Lead Engineer
> > MarkLogic Corporation
> > Phone: +1 512 761 6676
> > www.marklogic.com
> 
> 

Received on Sunday, 10 February 2013 15:19:59 UTC