Trouble with dynamically selected pipelines

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Trouble with dynamically selected pipelines

barandis
I'm new to OPS, but I seem to have gotten everything down pretty well so far. However, there is one thing that I'm having no luck with whatsoever.

I'm using OPS 3.0 beta 3. My site has a hierarchical directory structure where the XML content file is selected from the request URI (e.g., if /downloads/test.pri is requested, then /WEB-INF/resources/content/downloads/test.xml is the file I need...pretty basic). Each content file may need different processing based on which directory it's in, so I have a different pipeline for each directory (named, in each case, content.xpl).

Here are the important bits of what I have right now.

/WEB-INF/resources/page-flow.xml:

<page path-info="(/(.+)\.pri)" matcher="oxf:perl5-matcher"
      default-submission="content/default-submission.xml"
      model="content/assembler.xpl" view="content/xhtml.xsl">
   <setvalue ref="/request/request-uri" matcher-group="1"/>
   <setvalue ref="/request/page" matcher-group="2"/>
</page>


/WEB-INF/resources/content/default-submission.xml:

<request>
   <request-uri/>
   <page/>
</request>

/WEB-INF/resources/content/assembler.xpl:

<p:config xmlns:oxf="http://www.orbeon.com/oxf/processors"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:p="http://www.orbeon.com/oxf/pipeline">
   <p:param name="instance" type="input"/>
   <p:param name="data" type="output"/>
   <!-- Load the relevant XPL pipeline -->
   <p:processor name="oxf:xslt">
      <p:input name="data" href="#instance"/>
      <p:input name="config">
         <xsl:stylesheet version="2.0">
            <xsl:template match="/">
               <xsl:apply-templates select="request/page[1]"/>
            </xsl:template>
            <xsl:template match="page">
               <xsl:variable name="path" select="tokenize(.,'/')"/>
               <xsl:copy-of select="doc(concat(string-join(subsequence($path, 1, count($path) - 1), '/'), '/content.xpl'))"/>
            </xsl:template>
         </xsl:stylesheet>
      </p:input>
      <p:output name="data" id="content-pipeline"/>
   </p:processor>
   <!-- Process the pipeline -->
   <p:processor name="oxf:pipeline">
      <p:input name="config" href="#content-pipeline"/>
      <p:input name="request" href="#instance"/>
      <p:output name="data" id="content-doc"/>
   </p:processor>
   <!-- Add the header and footer -->
   <p:processor name="oxf:identity">
      <p:input name="data" href="aggregate('web-doc', common/header.xml, #content-doc, common/footer.xml)"/>
      <p:output name="data" ref="data"/>
   </p:processor>
</p:config>

/WEB-INF/resources/content/xhtml.xsl:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
   <xsl:template match="/">
      <xsl:copy-of select="."/>
   </xsl:template>
</xsl:stylesheet>

For the moment, I'm just trying to make the pipeline work; hence the basic XSL file.

As far as I can tell, since the 'href' attribute doesn't take variables, the only way to dynamically decide the file that it's processing is the way I did it, by using an embedded XSL transformation with an XPath doc() function in it. Since I'm wanting to dynamically choose my pipeline, this is how I did it here. And it works fine, even if it's not terribly elegant (please correct me if there's a better way).

The problem comes in the definition of the pipeline that assembler.xpl loads (content.xpl). This is what I have for the basic test pipeline.

/WEB-INF/resources/content/downloads/content.xpl:

<p:config xmlns:p="http://www.orbeon.com/oxf/pipeline"
      xmlns:oxf="http://www.orbeon.com/oxf/processors"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <p:param name="request" type="input"/>
   <p:param name="data" type="output"/>
   <p:processor name="oxf:xslt">
      <p:input name="data" href="#request"/>
      <p:input name="config">
         <xsl:stylesheet version="2.0">
            <xsl:template match="/">
               <xsl:apply-templates select="request/page"/>
            </xsl:template>
            <xsl:template match="page">
               <xsl:variable name="path" select="tokenize(., '/')"/>
               <xsl:copy-of select="doc(concat($path[last()], '.xml'))"/>
            </xsl:template>
         </xsl:stylesheet>
      </p:input>
      <p:output name="data" ref="data"/>
   </p:processor>
</p:config>

As you can see, there is no difference in logic whatsoever in the doc() function from the same function in assembler.xpl...only the relevent part of the URI is different (in assembler.xpl, it uses the base path, while here, it uses only the filename). In fact, I copy and pasted this from assembler.xpl and just changed the XPath expression.

However, this doesn't work. This throws a ValidationException with the message "no protocol:". It doesn't matter WHAT I put inside the doc() function...even a hardcoded URI, complete with a protocol...the same thing happens. It works fine if I use an oxf:identity processor (as a test) with a hardcoded URI, but that isn't sufficient for what I need.

This makes no sense to me, since the exact same thing works perfectly well in assembler.xpl (I even copy and pasted the expression exactly out of assembler.xpl, and it didn't work either). But I've tried everything I know and can't make it work. Any help would be appreciated, including telling me there's a better way if there is one.

Thanks.

-Barandis



--
You receive this message as a subscriber of the [hidden email] mailing list.
To unsubscribe: mailto:[hidden email]
For general help: mailto:[hidden email]?subject=help
ObjectWeb mailing lists service home page: http://www.objectweb.org/wws
Reply | Threaded
Open this post in threaded view
|

Re: Trouble with dynamically selected pipelines

dsmall-2

On Mon, 05 Sep 2005 20:30:55 +0200, [hidden email] said:

> I'm new to OPS, but I seem to have gotten everything down pretty well so
> far. However, there is one thing that I'm having no luck with whatsoever.
>
> I'm using OPS 3.0 beta 3. My site has a hierarchical directory structure
> where the XML content file is selected from the request URI (e.g., if
> /downloads/test.pri is requested, then
> /WEB-INF/resources/content/downloads/test.xml is the file I need...pretty
> basic). Each content file may need different processing based on which
> directory it's in, so I have a different pipeline for each directory
> (named, in each case, content.xpl).
>
> Here are the important bits of what I have right now.
Looks like the problem is that in the second use of the doc function
, the one in content.xpl, there is an attempt to contruct a relative
url with a base of "".  This happens because nothing tries to
set a system id on the xslt output, #content-pipeline, in
assembler.xpl.  

Btw no solution yet, just reporting what I have seen in the debugger.

-- Regards, Dan S

--
http://www.fastmail.fm - Faster than the air-speed velocity of an
                          unladen european swallow




--
You receive this message as a subscriber of the [hidden email] mailing list.
To unsubscribe: mailto:[hidden email]
For general help: mailto:[hidden email]?subject=help
ObjectWeb mailing lists service home page: http://www.objectweb.org/wws
Reply | Threaded
Open this post in threaded view
|

Re: Trouble with dynamically selected pipelines

dsmall-2
In reply to this post by barandis

On Mon, 05 Sep 2005 20:30:55 +0200, [hidden email] said:

> I'm new to OPS, but I seem to have gotten everything down pretty well so
> far. However, there is one thing that I'm having no luck with whatsoever.
>
> I'm using OPS 3.0 beta 3. My site has a hierarchical directory structure
> where the XML content file is selected from the request URI (e.g., if
> /downloads/test.pri is requested, then
> /WEB-INF/resources/content/downloads/test.xml is the file I need...pretty
> basic). Each content file may need different processing based on which
> directory it's in, so I have a different pipeline for each directory
> (named, in each case, content.xpl).
The next unstable build will a fix that lets you, I think, do what
you want.  However your code will need some tweaking.  ( See below. )

Fwiw the pbm was with the 2nd use of the doc function.  The code
assumes that your uri is a relative one and so tries to resolve.

However the doc that is being used as a context for resolution
is the 'content.xpl' that was by assembler.xpl.  Since there was no
system id available for this doc an exception was thrown.

So what I did was to change the xslt processor so that it tries to
set a system id on its output doc in the event that one isn't
already set.  

And, as I said, there were still changes needed to your code.
The pbm there is that if the generated content.xpl has a uri
of oxf:/content/assember.xpl and the file it is meant to
be loading is oxf:/content/downloads/test.xml then the
relative uri downloads/test.xml won't work.  

The changed code follows.  The main difference is the
work around for this last problem.  The problem is
dealt with by having content.xpl contain an incomplete
variable decl which assembler.xpl fills in with the
'context' uri for content.xpl.

page-flow :

<page path-info='(/.+\.pri)' matcher='oxf:perl5-matcher'
  default-submission='content/default-submission.xml'
  model='content/assembler.xpl' view='content/xhtml.xsl'>
  <setvalue ref='/request/file' matcher-group='1'/>
</page>  

content.xpl :

<p:config xmlns:p='http://www.orbeon.com/oxf/pipeline'
  xmlns:oxf='http://www.orbeon.com/oxf/processors'
  xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
>
  <p:param name='request' type='input' />
  <p:param name='data' type='output' />
  <p:processor name='oxf:xslt' >
    <p:input name='data' href='#request' />
    <p:input name='config' >
      <xsl:stylesheet version='2.0' >
        <xsl:template match='/' >
          <xsl:variable name='mypath' />
          <xsl:copy-of select='doc( replace( $mypath, "^(.*)/[^/]+$",
          "$1/test.xml" ) )' />
        </xsl:template>
       </xsl:stylesheet>
    </p:input>
    <p:output name='data' ref='data' />
  </p:processor>
</p:config>

assembler.xpl :

<p:config xmlns:oxf='http://www.orbeon.com/oxf/processors'
  xmlns:xsl='http://www.w3.org/1999/XSL/Transform' 
  xmlns:p='http://www.orbeon.com/oxf/pipeline'
>
  <p:param name='instance' type='input' />
  <p:param name='data' type='output' />
  <!-- Load the relevant XPL pipeline -->
  <p:processor name='oxf:xslt'>
    <p:input name='data' href='#instance' />
    <p:input name='config' >
      <xsl:stylesheet version='2.0'>
        <xsl:template match='/'>
          <xsl:variable name='path-tokens' select='tokenize(
          /request/file, "/" )'/>
          <xsl:variable name='path' select='replace( /request/file,
          "^/(.*)/[^/]+$", "$1/content.xpl" )' />
          <xsl:variable name='xpl-doc' select='doc( $path )' />
          <xsl:variable name='xpl-uri' select='resolve-uri(
          document-uri( $xpl-doc ) )'/>
          <xsl:apply-templates select='$xpl-doc/p:config' mode='xpl' >
            <xsl:with-param name='xpl-uri' select='$xpl-uri'
            tunnel='yes' />
          </xsl:apply-templates>
        </xsl:template>
        <xsl:template match='@*|node()' mode='xpl' >
          <xsl:copy>
            <xsl:apply-templates select='@*|node()' mode='#current' />
          </xsl:copy>
        </xsl:template>
        <xsl:template match='//xsl:variable' mode='xpl' >
          <xsl:param name='xpl-uri' tunnel='yes' />
          <xsl:choose>
            <xsl:when test='./@name="mypath"' >
              <xsl:copy>
                <xsl:attribute name='select' select='concat( "&apos;",
                $xpl-uri, "&apos;" )' />
                <xsl:apply-templates select='node()|@* except @select'
                mode='#current' />                
              </xsl:copy>
            </xsl:when>
            <xsl:otherwise>
              <xsl:copy>
                <xsl:apply-templates select='node()|@*' mode='#current'
                />                
              </xsl:copy>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:template>
      </xsl:stylesheet>
    </p:input>
    <p:output name='data' id='content-pipeline'/>
  </p:processor>
  <!-- Process the pipeline -->
  <p:processor name='oxf:pipeline'>
    <p:input name='config' href='#content-pipeline'/>
    <p:input name='request' href='#instance'/>
    <p:output name='data' id='content-doc'/>
  </p:processor>
  <!-- Add the header and footer -->
  <p:processor name='oxf:identity'>
    <p:input name='data' href="aggregate('web-doc', common/header.xml,
    #content-doc, common/footer.xml)"/>
    <p:output name='data' ref='data'/>
  </p:processor>
</p:config>



-- Regards, Dan S



--
http://www.fastmail.fm - A fast, anti-spam email service.




--
You receive this message as a subscriber of the [hidden email] mailing list.
To unsubscribe: mailto:[hidden email]
For general help: mailto:[hidden email]?subject=help
ObjectWeb mailing lists service home page: http://www.objectweb.org/wws