You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cocoon.apache.org by Ken Beyer <ka...@metatec.com> on 2000/05/23 23:33:19 UTC

Choosing an XSL dynamically

Can I do the following in Cocoon 1.7.4? ...

Have different portals (i.e. foo and bar)
and have test.xml?portal=foo -> test.foo.xsl
when portal foo is being accessed (e.g.
through a passed parameter), and
similarly have test.xml?portal=bar -> test.bar.xsl
when bar is being accessed.  You see
the XML data is always the same format,
but I want to present it different for
different portals.

I need to somehow dynamically decide
which XSL to use.  Problem is I need
a static line in test.xml like:
<?xml-stylesheet href="test.xsl" type="text/xsl"?>

Does it make sense to write a broker XSL like:
<?xml-stylesheet href="test.broker.xsl" type="text/xsl"?>
and have that copy the contents and call the
proper XSL (based on portal) dynamically?
<note>
I tried this, but can't quite get the broker to
invoke the 2nd XSL on the output of the 1st. maybe
my copy's not working right - because output of
my broker XSL looks like:
<page>
<?cocoon-process type="xslt"?>
<?xml-stylesheet href="test.foo.xsl" type="text/xsl" ?>
              <test>
                Hello!
              </test>
</page>
<!-- This page was served in 82 milliseconds by Cocoon 1.7.4 -->
Notice how the <page> root element/tag is out of place.
</note>

If I can't do this, then does anyone have another
suggestion to pull off what I'm trying to do?

Do I have to go with Servlets/Xalan to pull this off,
or can I use XSP built-in funcs or utils, or Xinclude,
or whatever?  Or maybe there's something wrong with
my design because it seems like it should be a pretty
common problem.  I read that Cocoon 2 might support
this, but I can't really wait that long.

Thanks-
Ken




Re: Choosing an XSL dynamically

Posted by Ken Beyer <ka...@metatec.com>.
Okay thanks - but I only put the XSP in it to make sure that
that extra processing didn't affect anything adversly.   I basically
just needed to understand how to get the "brokering" part to work,
which is where your code snippet came in quite handy - thx!
But I'm doing more checks, like authentication users via
LDAP  & SQL, that they have permissions to access certain portals
and then that those portal files actually exist, etc - so I'll have
plenty of security type checks in when all's said & done.

Only thing I'm still not sure of is am I really approaching
this the right way?, or should I use dynamic  xsl:include,
xsl:import or xinclude or whatnot?

If  I'm completely clueless, and there's a _better_ way
to achieve this dynamic-type XSL loading in Cocoon,
heck I'm all ears :-)   Right now it looks like I'll process all
my XML output (from different XSPs) via a "broker.xsl"
which will be responsible for loading the right XSL's
per portal per XSP.

Ken

Hans Ulrich Niedermann wrote:

> Ken Beyer <ka...@metatec.com> writes:
>
> > <xsp:page language="java"
> > xmlns:xsp="http://www.apache.org/1999/XSP/Core">
>
> You don't need XSP to select a XSL stylesheet dynamically. My solution
> doesn't need XSP.
>
> [ ... ]
>
> >    <xsl:processing-instruction
> > name="cocoon-process">type="xslt"</xsl:processing-instruction>
> >    <xsl:processing-instruction name="xml-stylesheet">
> >    href="test.<xsl:value-of select="$portal"/>.xsl"
> >    type="text/xsl"
> >    </xsl:processing-instruction>
>
> I'd prefer to check the values of $portal and match them agains a
> fixed list. Else any remote user may try to find out what your XSL
> files do, what your XML file contains (?portal=test.broker.xsl)
> etc. pp.
>
> Uli
> --
> Hans Ulrich Niedermann      <ni...@normans.isd.uni-stuttgart.de>
> Systemadministration        http://www.normans.isd.uni-stuttgart.de/
> Institut für Statik und Dynamik der Luft- und Raumfahrtkonstruktionen
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: cocoon-users-unsubscribe@xml.apache.org
> For additional commands, e-mail: cocoon-users-help@xml.apache.org


Re: Choosing an XSL dynamically

Posted by Hans Ulrich Niedermann <ni...@isd.uni-stuttgart.de>.
Ken Beyer <ka...@metatec.com> writes:

> <xsp:page language="java"
> xmlns:xsp="http://www.apache.org/1999/XSP/Core">

You don't need XSP to select a XSL stylesheet dynamically. My solution
doesn't need XSP. 

[ ... ]

>    <xsl:processing-instruction
> name="cocoon-process">type="xslt"</xsl:processing-instruction>
>    <xsl:processing-instruction name="xml-stylesheet">
>    href="test.<xsl:value-of select="$portal"/>.xsl"
>    type="text/xsl"
>    </xsl:processing-instruction>

I'd prefer to check the values of $portal and match them agains a
fixed list. Else any remote user may try to find out what your XSL
files do, what your XML file contains (?portal=test.broker.xsl)
etc. pp.

Uli
-- 
Hans Ulrich Niedermann      <ni...@normans.isd.uni-stuttgart.de>
Systemadministration         http://www.normans.isd.uni-stuttgart.de/
Institut für Statik und Dynamik der Luft- und Raumfahrtkonstruktionen

Re: Choosing an XSL dynamically

Posted by Ken Beyer <ka...@metatec.com>.
Thanks Ulrich - that works!  A couple of minor errors in
yours so for clarity (in case others wish to see,
here's the sample files that worked on my machine).

I apologize if this is common knowledge to others -
just I went through mail archives and didn't see any
solutions on prior "similar" threads.

-------------------
<?xml version="1.0"?>

<!-- test.xml (i.e. test.xml?portal=foo) -->

<?cocoon-process type="xsp"?>
<?cocoon-process type="xslt"?>
<?xml-stylesheet href="test.broker.xsl" type="text/xsl"?>

<xsp:page language="java"
xmlns:xsp="http://www.apache.org/1999/XSP/Core">

<xsp:logic>
 String someXspString = "foobar";
</xsp:logic>

<page>
  SOME XML DATA <xsp:expr>someXspString</xsp:expr>
</page>

</xsp:page>

-------------------------
<?xml version="1.0"?>

<!-- test.broker.xsl -->

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

  <xsl:param name="portal"/>

  <xsl:template match="page">
   <xsl:processing-instruction
name="cocoon-process">type="xslt"</xsl:processing-instruction>
   <xsl:processing-instruction name="xml-stylesheet">
   href="test.<xsl:value-of select="$portal"/>.xsl"
   type="text/xsl"
   </xsl:processing-instruction>
   <xsl:comment>Using portal = <xsl:value-of
select="$portal"/></xsl:comment>
   <xsl:copy>
    <xsl:apply-templates select="@*"/>
    <xsl:apply-templates select="node()"/>
   </xsl:copy>
  </xsl:template>

  <xsl:template match="@*|*">
   <xsl:copy>
    <xsl:apply-templates select="*|@*"/>
   </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

------------------------
<?xml version="1.0"?>

<!-- test.foo.xsl -->

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

  <xsl:template match="page">
    <xsl:processing-instruction
name="cocoon-format">type="text/html"</xsl:processing-instruction>
   <html>
    <head>
     <title>
      Hello from foo
     </title>
    </head>
     Hello from foo!
     <P>Here's your data ... </P>
     <xsl:apply-templates/>
    </html>
  </xsl:template>

</xsl:stylesheet>

---------------------
<?xml version="1.0"?>

<!-- test.bar.xsl -->

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

  <xsl:template match="page">
    <xsl:processing-instruction
name="cocoon-format">type="text/html"</xsl:processing-instruction>
   <html>
    <head>
     <title>
      Hello from bar
     </title>
    </head>
     Hello from bar!
     <P>Here's your data ... </P>
     <xsl:apply-templates/>
    </html>
  </xsl:template>

</xsl:stylesheet>

Ken



Re: Choosing an XSL dynamically

Posted by Hans Ulrich Niedermann <ni...@isd.uni-stuttgart.de>.
Ken Beyer <ka...@metatec.com> writes:

> I need to somehow dynamically decide
> which XSL to use.  Problem is I need
> a static line in test.xml like:
> <?xml-stylesheet href="test.xsl" type="text/xsl"?>
> 
> Does it make sense to write a broker XSL like:
> <?xml-stylesheet href="test.broker.xsl" type="text/xsl"?>
> and have that copy the contents and call the
> proper XSL (based on portal) dynamically?
> <note>
> I tried this, but can't quite get the broker to
> invoke the 2nd XSL on the output of the 1st. maybe
> my copy's not working right - because output of
> my broker XSL looks like:
> <page>
> <?cocoon-process type="xslt"?>
> <?xml-stylesheet href="test.foo.xsl" type="text/xsl" ?>
>               <test>
>                 Hello!
>               </test>
> </page>
> <!-- This page was served in 82 milliseconds by Cocoon 1.7.4 -->
> Notice how the <page> root element/tag is out of place.
> </note>

Just create your the processing instructions outside of the <page>
element. 

<!-- this is the XML data file -->
<?cocoon-process type="xslt"?>
<?xml-stylesheet href="broker.xsl" type="text/xsl"?>
<page>
  ... stuff ...
</page>

<!-- this is broker.xsl -->
<xsl:stylesheet ...>
  <xsl:param name="portal"/>

  <xsl:template match="page">
    <xsl:processing-instruction name="cocoon-process">
      type="xslt"
    </xsl:processing-instruction>
    <xsl:processing-instruction name="xml-stylesheet">
      <xsl:choose>  
        <xsl:when test="$portal='foo'">oneportal.xsl</xsl:when>
        <xsl:when test="$portal='bar'">anotherportal.xsl</xsl:when>
        <xsl:otherwise>Barf!</xsl:otherwise>
      </xsl:choose>
    </xsl:processing-instruction>
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:apply-templates select="node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*|@*">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

This is untested, but you should get the idea.

Uli

Re: Choosing an XSL dynamically

Posted by Michael Bierenfeld <mi...@atmiralis.de>.
Ken Beyer wrote:
> 
> Can I do the following in Cocoon 1.7.4? ...
> 
> Have different portals (i.e. foo and bar)
> and have test.xml?portal=foo -> test.foo.xsl
> when portal foo is being accessed (e.g.
> through a passed parameter), and
> similarly have test.xml?portal=bar -> test.bar.xsl
> when bar is being accessed.  You see
> the XML data is always the same format,
> but I want to present it different for
> different portals.
> 
> I need to somehow dynamically decide
> which XSL to use.  Problem is I need
> a static line in test.xml like:
> <?xml-stylesheet href="test.xsl" type="text/xsl"?>
> 
> Does it make sense to write a broker XSL like:
> <?xml-stylesheet href="test.broker.xsl" type="text/xsl"?>
> and have that copy the contents and call the
> proper XSL (based on portal) dynamically?
> <note>
> I tried this, but can't quite get the broker to
> invoke the 2nd XSL on the output of the 1st. maybe
> my copy's not working right - because output of
> my broker XSL looks like:
> <page>
> <?cocoon-process type="xslt"?>
> <?xml-stylesheet href="test.foo.xsl" type="text/xsl" ?>
>               <test>
>                 Hello!
>               </test>
> </page>
> <!-- This page was served in 82 milliseconds by Cocoon 1.7.4 -->
> Notice how the <page> root element/tag is out of place.
> </note>
> 
> If I can't do this, then does anyone have another
> suggestion to pull off what I'm trying to do?
> 
> Do I have to go with Servlets/Xalan to pull this off,
> or can I use XSP built-in funcs or utils, or Xinclude,
> or whatever?  Or maybe there's something wrong with
> my design because it seems like it should be a pretty
> common problem.  I read that Cocoon 2 might support
> this, but I can't really wait that long.
> 
> Thanks-
> Ken
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: cocoon-users-unsubscribe@xml.apache.org
> For additional commands, e-mail: cocoon-users-help@xml.apache.org


Hello,

we have done this together with xsp + xsl.

Style sheet for the content page is allways the xsp-File. 

and the page tag uses

<page stylesheet="hello.xsl"> that is catched in the xsp-file with :

  <xsl:template match="page">

    <!-- ********************************************************************* -->
    <!-- Processing instructions                                               -->

    <xsl:processing-instruction name="cocoon-process">
	type="xsp"
    </xsl:processing-instruction>

    <xsl:processing-instruction name="cocoon-process">
	type="xslt"
    </xsl:processing-instruction>
    
    <!-- *********************************************************************** -->
    <!-- Definition des zu verwendenden Stylesheets                              -->

    <xsl:processing-instruction name="xml-stylesheet">
	href=<xsl:text>"</xsl:text><xsl:value-of select="@stylesheet"/><xsl:text>"</xsl:text>
	type="text/xsl"
    </xsl:processing-instruction>

Regards

Michael