Search

Hey guys. Hope someone can enlighten me.

I'm still new to XSLT, so bare with me.

I currently have a Pages and Sections Section. The Pages are linked to the Sections and each Section and Page can have a body. I have two data sources that provide the Current Page and Current Section.

What this sums up is that I have 2 data sources that eventually only one of the two will have data. In particular, the logic is as follows:

If there is a page defined, then display that. Otherwise, display the section content.

This seemed to work nicely at first and I did the following to solve my varying data source:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
extension-element-prefixes="dyn exslt"
xmlns:exslt="http://exslt.org/common"
xmlns:dyn="http://exslt.org/dynamic">

<xsl:variable name="page" select="$current-page" />
<xsl:variable name="type">
    <xsl:choose>
        <xsl:when test="string-length($page) > 0">
            page
        </xsl:when>
        <xsl:otherwise>current-section</xsl:otherwise>
    </xsl:choose>
</xsl:variable>
<xsl:variable name="entry" select="dyn:evaluate(concat('/data/', $type, '/title/entry'))" />
    <xsl:variable name="content" elect="$entry/body" />
...

I used EXSLT to evaluate the correct xpath for the right entry.


Here's the problem. There are some pages that I don't care so much about the content that someone puts in the body (field). Say for instance that I would like to print out a list of records. There's no need for a body for that page. Instead the content is going to be generated by XSLT. I realized, though, that there are some parts of the page that look at the $content variable for setting the right element attributes of the page.

For example, I will only display a navigation column if the $content has any headers (h2-4) and if the $content is rather large (at least 1250 characters):

<xsl:variable name="entry" select="dyn:evaluate(concat('/data/', $type, '/title/entry'))" />
    ...
<xsl:variable name="need-page-navigation" select="count($content[h2|h3|h4]) > 0 and $large-content" />

This is a bit of a problem. $content right now is only from a xml node. The path to that node (the body node) may be different, but the evaluation takes care of that issue.

So I was thinking that why not make a new variable $contents with the $content and a variable content that of the additional content -- transformed content from xslt. Basically a mash-up or a union of the two.

Here's the immediate attempt:

<xsl:variable name="contents">
    <xsl:copy-of select="$content" />
    <xsl:copy-of select="$page-content" />
</xsl:variable>

Where (for now) $page-content is:

<xsl:variable name="page-content">
    <xsl:element name="h3">
        <xsl:value-of select="hello world" />
    </xsl:element>
</xsl:variable>

The immediate error is as follows

From what I gathered from the web, is that the "tree fragment" created by the xsl:variable is not allowed to work with count() and other functions. I thought I would use exsl:node-set() but for some reason I am timing out.

Is this how you (gurus) would approach this? Am I doing something stupid? :D

Thanks for the help, and insight.

Olmo

hey olmo, just looked at the error you're getting and noticed this:

XSLTProcessor::transformToXml(): unregistered variable need-page-navigation

do you have the need-page-navigation variable defined wherever you're doing this transformation? also, can you post snippets from your page-utilities.xsl file? i see the processor saw an error at lines 25 and 30. so maybe post a good size chunk of that xsl file.

Not a problem. Here's the actual page-utilities.xsl.

As you can see the variable is defined in that same xsl. It's the error that is produced with count(...) on line 25 that is the issue.

I believe that since I am trying to apply an XPATH function to a resultant tree fragment (RTF) I am getting these errors (at least inside the .xsl).

Is there a better way to do this without having to deal with tree fragments? (in case I can't figure out why exslt:node-set(...) times out)

Thanks for helping out.

Hey wtdtan, I'm getting closer.

Here's the update to the .xsl:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    extension-element-prefixes="dyn com"
    xmlns:com="http://exslt.org/common"
    xmlns:dyn="http://exslt.org/dynamic">

    <xsl:variable name="contents">
        <xsl:copy-of select="$entry/body" />
        <xsl:copy-of select="$page-content" />
    </xsl:variable>
    <xsl:variable name="content" select="com:node-set($contents)/*" />

So I was right that the node-set should do the trick to convert a Result Tree Fragment into a node-set so I can apply the xpath functions to the tree/node-set. The following, though, caused a time out for my page access:

<xsl:variable name="content" select="com:node-set($contents)" />

If I had to guess, it'd be that I was selecting the fake root node of the node-set and libxslt went crazy.

I'm still having a small issue now, though, that:

<xsl:variable name="need-page-navigation" select="count($content[h2|h3|h4]) > 0" />

Shows up as false. Even though my $page-content:

<xsl:variable name="page-content">
    <h2>test</h2>
</xsl:variable>

Has a h2 element. I'm guessing this is a path problem, so I'll keep debugging.

Ok.. Hurray..

Here's the last piece of the puzzle:

<xsl:variable name="page-content">
    <body>
        <h2>test</h2>
    </body>
</xsl:variable>

So what happened is that my page entry has a field named body. Since I was consolidating the two node-sets into one, I had to have the same parent node (body). I might try (later on) to figure out how to get rid of this requirement, but for now I'll keep progressing.

Ok so another update.

I've removed the body element from the $page-content by doing the following with the $content variable:

<xsl:variable name="contents">
    <body>
        <xsl:copy-of select="$entry/body/*" />
        <xsl:copy-of select="$page-content" />
    </body>
</xsl:variable>

:)

sorry couldn't have been more of a help ibolmo. i ran out the door after my post yesterday.

No worries wtdtan :).

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details