How to hide content using XSL parameters
You can hide part of the content in large documents to speed up your editor
When working with large documents Xopus may become slow. In such a case it is an option to hide part of the content through the use of an XSL parameter.
Slow Xopus
SDL LiveContent Create transforms the loaded XML file to HTML for display in the browser using XSL. SDL LiveContent Create adds events and id's to the HTML to be able to 'listen' to editing actions. SDL LiveContent Create translates these actions to the XML and whenever an action occurs SDL LiveContent Create will trigger the XSL again.
SDL LiveContent Create will then compare the old HTML to the new HTML and update the differences. This is a bottleneck in SDL LiveContent Create . A large XML file will cause a lot of HTML and comparing all that HTML will slow SDL LiveContent Create down.
Using XSL to speed up the rendering
Xopus will be faster when the HTML output of the XSL is smaller. There are two ways to make the HTML output of the XSL smaller:
- Load a smaller XML file
- Output less from the XSL, despite the large input
Option one is obvious. Most large documents have chapters, parts or sections and therefore can be rendered as a table of contents. Using this table of contents you can load smaller sections of a document into Xopus. Because you are no longer transforming the whole XML to HTML in Xopus, it will be much easier to work with for Xopus.
Option two is a little sneakier. You can still let Xopus load the whole XML file, but use the XSL to render both the table of contents and the smaller section that you want to edit. This way the HTML output is much smaller and therefore more manageable.
Using a parameter
As an example we will look at the following XML document:
<document>
<chapter id="A"/>
<chapter id="B"/>
<chapter id="C"/>
<chapter id="D"/>
<chapter id="E"/>
</document>
Let's assume that this document's chapters are very big and that we only want to render one chapter at a time. We can do this with a parameter in the XSL:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="showChapter" select="'A'"/>
<xsl:template match="chapter">
<xsl:choose>
<xsl:when test="@id = $showChapter">
<!-- render chapter -->
<div>
<xsl:apply-templates select="node()"/>
</div>
</xsl:when>
<xsl:otherwise>
<!-- don't render chapter -->
</xsl:otherwise>
</xsl:choose>
</xsl:choose>
...
As you can see from the above XSL, only when the chapter/id attribute matches the value of the showChapter parameter will the chapter be rendered. A nice way to allow the other chapters to be 'selectable', is to do the following:
...
<xsl:otherwise>
<!-- don't render chapter, but render the title, and make it clickable -->
<a href="#"
onclick="Editor.getActiveCanvas().setViewParam('showChapter', '{@id}');">
<xsl:apply-templates select="title"/>
</a>
</xsl:otherwise>
...
Now the rendering will show one complete chapter, and the titles of the other chapter. These titles will be clickable as links, and when clicked will set the value of the parameter to the id attribute of the current chapter.
This is the main idea for using a parameter to render only a part of a document. It involves making the XSL 'smarter' and more interactive. Please note that this does make the XSL less usable outsideSDL LiveContent Create .
Other XML and more brower differences
Not all XML will have id attributes. This is why for a long time we simple passed the node itself to the parameter and used the XSL generate-id() function to test the node as the active one:
<xsl:param name="showChapter" select="//chapter[1]"/>
<xsl:template match="chapter">
<xsl:choose>
<xsl:when test="generate-id(.) = generate-id($showChapter)">
...
The example compares the current node "." to the showChapter parameter through the use of the generate-id() function. It is also possible to set the node as the parameter in the onclick:
<a href="#" onclick="Editor.getActiveCanvas().setViewParam('showChapter', node);">
...
The node argument that you can see being passed to the parameter will always refer to the node from the xsl:template match statement. This node can be used to access the API: it is an XopusNode. The above functionality works fine in Internet Explorer as well as Firefox. Chrome however does not support the passing of nodes as parameter values. To create an XSL that works in all three browsers, we fall back to comparing a id value, but this time we use the ids as assigned by SDL LiveContent Create .
<xsl:template name="getId">
<xsl:variable name="id" select="substring-before(following::processing-instruction('xopus-node')[1], '*')" />
<xsl:choose>
<xsl:when test="starts-with($id, '+')">
<xsl:value-of select="substring-after($id, '+')" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$id" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
The above template returns an id that can be used for our tests. It should be added to your XSL. It is used in the following:
<xsl:param name="showChapter" select="''"/>
<xsl:template match="chapter">
<xsl:variable name="id"><xsl:call-template name="getId" /></xsl:variable>
<xsl:choose>
<xsl:when test="$id = $showChapter">
...
<a href="#" onclick="Editor.getActiveCanvas().setViewParam('showChapter', '{$id}');">
...