You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Ovidiu Predescu <ov...@cup.hp.com> on 2000/09/21 18:59:56 UTC

portable usage of extension functions in XSLT?

Hi,

I'm in the process of writing a set of stylesheets for WML generation which
eventually will be donated to the Cocoon project. There are certain features of
WML that are not supported by all the browsers so I need to generate custom WML
depending on the user agent. I maintain a collection of XML descriptions for
each known device; my stylesheets are making use of them to generate the
appropriate WML.

There are two ways I can check in my stylesheet for a particular feature
supported by the browser. The first is to include the XML corresponding to the
browser in my stylesheet as another document and do checks based on the tree.
It works something like this:


<xsl:param name="user-agent"/>
<xsl:variable name="hasAccessKey"
   select="document(concat('ua:/user-agent=', $user-agent))//hasAccessKey/@valu
e"/>

<xsl:template match="link">
 <xsl:param name="position"/>
 <anchor>
  <xsl:if test="$hasAccessKey">
   <xsl:attribute name="accesskey">
    <xsl:value-of select="$position"/>
   </xsl:attribute>
  </xsl:if>
  <go href="{@href}"/>
 </anchor>
</xsl:template>

'ua' is a new URL protocol I came up with and is handled internally by Cocoon.
It looks at the user agent string and simply returns the appropriate XML
document, which is then imported in the stylesheet.

The second approach would be to use extension functions, but from what I see XT
and Xalan use different conventions for specifying the XML namespace.

in Xalan:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:lxslt="http://xml.apache.org/xslt"
  xmlns:ua="class:org.apache.cocoon.wml.UserAgentCapabilities"
  extension-element-prefixes="ua"
  version="1.0"
>

in XT:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:lxslt="http://xml.apache.org/xslt"
  xmlns:ua="http://www.jclark.com/xt/java/org.apache.cocoon.wml.UserAgentCapabi
lities"
  version="1.0"
>

Using either of these, one could then write the above 'link' template like
this:

<xsl:template match="link">
 <xsl:param name="position"/>
 <anchor>
  <xsl:if test="ua:hasAccessKey($user-agent)">
   <xsl:attribute name="accesskey">
    <xsl:value-of select="$position"/>
   </xsl:attribute>
  </xsl:if>
  <go href="{@href}"/>
 </anchor>
</xsl:template>

The first solution, importing the XML in the XSL stylesheet, is portable, no
matter the XSLT processor we use. The drawback however is that the user-agent
specific XML document is parsed every time, which has an impact on memory and
speed. The second approach, while cleaner, has the disadvantage that it depends
on the XSLT processor used.

What would be a good solution to this problem? Do we care about cross XSLT
processor issues or a less portable solution would be good enough?

Thanks,
Ovidiu

-- 
Ovidiu Predescu <ov...@cup.hp.com>
http://orion.nsr.hp.com/ (inside HP's firewall only)
http://www.geocities.com/SiliconValley/Monitor/7464/



Re: portable usage of extension functions in XSLT?

Posted by Stefano Mazzocchi <st...@apache.org>.
Ovidiu Predescu wrote:
> 
> Hi,
> 
> I'm in the process of writing a set of stylesheets for WML generation which
> eventually will be donated to the Cocoon project. There are certain features of
> WML that are not supported by all the browsers so I need to generate custom WML
> depending on the user agent. I maintain a collection of XML descriptions for
> each known device; my stylesheets are making use of them to generate the
> appropriate WML.
> 
> There are two ways I can check in my stylesheet for a particular feature
> supported by the browser. The first is to include the XML corresponding to the
> browser in my stylesheet as another document and do checks based on the tree.
> It works something like this:
> 
> <xsl:param name="user-agent"/>
> <xsl:variable name="hasAccessKey"
>    select="document(concat('ua:/user-agent=', $user-agent))//hasAccessKey/@valu
> e"/>
> 
> <xsl:template match="link">
>  <xsl:param name="position"/>
>  <anchor>
>   <xsl:if test="$hasAccessKey">
>    <xsl:attribute name="accesskey">
>     <xsl:value-of select="$position"/>
>    </xsl:attribute>
>   </xsl:if>
>   <go href="{@href}"/>
>  </anchor>
> </xsl:template>
> 
> 'ua' is a new URL protocol I came up with and is handled internally by Cocoon.
> It looks at the user agent string and simply returns the appropriate XML
> document, which is then imported in the stylesheet.
> 
> The second approach would be to use extension functions, but from what I see XT
> and Xalan use different conventions for specifying the XML namespace.
> 
> in Xalan:
> 
> <xsl:stylesheet
>   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>   xmlns:lxslt="http://xml.apache.org/xslt"
>   xmlns:ua="class:org.apache.cocoon.wml.UserAgentCapabilities"
>   extension-element-prefixes="ua"
>   version="1.0"
> >
> 
> in XT:
> 
> <xsl:stylesheet
>   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>   xmlns:lxslt="http://xml.apache.org/xslt"
>   xmlns:ua="http://www.jclark.com/xt/java/org.apache.cocoon.wml.UserAgentCapabi
> lities"
>   version="1.0"
> >
> 
> Using either of these, one could then write the above 'link' template like
> this:
> 
> <xsl:template match="link">
>  <xsl:param name="position"/>
>  <anchor>
>   <xsl:if test="ua:hasAccessKey($user-agent)">
>    <xsl:attribute name="accesskey">
>     <xsl:value-of select="$position"/>
>    </xsl:attribute>
>   </xsl:if>
>   <go href="{@href}"/>
>  </anchor>
> </xsl:template>
> 
> The first solution, importing the XML in the XSL stylesheet, is portable, no
> matter the XSLT processor we use. The drawback however is that the user-agent
> specific XML document is parsed every time, which has an impact on memory and
> speed. The second approach, while cleaner, has the disadvantage that it depends
> on the XSLT processor used.
> 
> What would be a good solution to this problem? Do we care about cross XSLT
> processor issues or a less portable solution would be good enough?

I'd go for portability now.

Anyway, are you doing this for C1 or C2?

-- 
Stefano Mazzocchi      One must still have chaos in oneself to be
                          able to give birth to a dancing star.
<st...@apache.org>                             Friedrich Nietzsche
--------------------------------------------------------------------
 Missed us in Orlando? Make it up with ApacheCON Europe in London!
------------------------- http://ApacheCon.Com ---------------------



Re: portable usage of extension functions in XSLT?

Posted by Zvi <th...@ifrance.com>.
the second is better, just write for Xalan, and if somebody will be interested in
other XSLT processor like XT, he/she will port it.

the 3rd solution is to pass the entire UserAgent capabilities document as
parameter, using <xsl:param>.



Ovidiu Predescu wrote:

> Hi,
>
> I'm in the process of writing a set of stylesheets for WML generation which
> eventually will be donated to the Cocoon project. There are certain features of
> WML that are not supported by all the browsers so I need to generate custom WML
> depending on the user agent. I maintain a collection of XML descriptions for
> each known device; my stylesheets are making use of them to generate the
> appropriate WML.
>
> There are two ways I can check in my stylesheet for a particular feature
> supported by the browser. The first is to include the XML corresponding to the
> browser in my stylesheet as another document and do checks based on the tree.
> It works something like this:
>
> <xsl:param name="user-agent"/>
> <xsl:variable name="hasAccessKey"
>    select="document(concat('ua:/user-agent=', $user-agent))//hasAccessKey/@valu
> e"/>
>
> <xsl:template match="link">
>  <xsl:param name="position"/>
>  <anchor>
>   <xsl:if test="$hasAccessKey">
>    <xsl:attribute name="accesskey">
>     <xsl:value-of select="$position"/>
>    </xsl:attribute>
>   </xsl:if>
>   <go href="{@href}"/>
>  </anchor>
> </xsl:template>
>
> 'ua' is a new URL protocol I came up with and is handled internally by Cocoon.
> It looks at the user agent string and simply returns the appropriate XML
> document, which is then imported in the stylesheet.
>
> The second approach would be to use extension functions, but from what I see XT
> and Xalan use different conventions for specifying the XML namespace.
>
> in Xalan:
>
> <xsl:stylesheet
>   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>   xmlns:lxslt="http://xml.apache.org/xslt"
>   xmlns:ua="class:org.apache.cocoon.wml.UserAgentCapabilities"
>   extension-element-prefixes="ua"
>   version="1.0"
> >
>
> in XT:
>
> <xsl:stylesheet
>   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>   xmlns:lxslt="http://xml.apache.org/xslt"
>   xmlns:ua="http://www.jclark.com/xt/java/org.apache.cocoon.wml.UserAgentCapabi
> lities"
>   version="1.0"
> >
>
> Using either of these, one could then write the above 'link' template like
> this:
>
> <xsl:template match="link">
>  <xsl:param name="position"/>
>  <anchor>
>   <xsl:if test="ua:hasAccessKey($user-agent)">
>    <xsl:attribute name="accesskey">
>     <xsl:value-of select="$position"/>
>    </xsl:attribute>
>   </xsl:if>
>   <go href="{@href}"/>
>  </anchor>
> </xsl:template>
>
> The first solution, importing the XML in the XSL stylesheet, is portable, no
> matter the XSLT processor we use. The drawback however is that the user-agent
> specific XML document is parsed every time, which has an impact on memory and
> speed. The second approach, while cleaner, has the disadvantage that it depends
> on the XSLT processor used.
>
> What would be a good solution to this problem? Do we care about cross XSLT
> processor issues or a less portable solution would be good enough?
>
> Thanks,
> Ovidiu
>
> --
> Ovidiu Predescu <ov...@cup.hp.com>
> http://orion.nsr.hp.com/ (inside HP's firewall only)
> http://www.geocities.com/SiliconValley/Monitor/7464/
>
>   ------------------------------------------------------------------------
>    Part 1.2Type: application/pgp-signature