21
Advanced XSL Learn how to use advanced XSLT techniques, EXSLT, and Xalan extensions to solve complicated problems. 2008 Cascade Server User’s Conference Amy Liu & Brett Goodwin

Advanced XSL Learn how to use advanced XSLT techniques, EXSLT, and Xalan extensions to solve complicated problems. 2008 Cascade Server User’s ConferenceAmy

Embed Size (px)

Citation preview

Advanced XSL

Learn how to use advanced XSLT techniques, EXSLT, and Xalan extensions

to solve complicated problems.

2008 Cascade Server User’s Conference Amy Liu & Brett Goodwin

Amy Liu & Brett Goodwin

Agenda

XSL & XSLTXSLT Warmup

Muenchian MethodEXSLT

Xalan ExtensionsVelocity Script Formats

09/22/2008

Amy Liu & Brett Goodwin

XSL & XSLT

• XSL (eXtensible Stylesheet Language) consists of three parts:– XSLT

a language for transforming XML documents

– XPatha language for navigating in XML documents

– XSL:FOa language for formatting XML documents

09/22/2008

Amy Liu & Brett Goodwin

http://www.w3schools.com/xsl/xsl_w3celementref.asp

XSLT Warmup• <xsl:template match=“xpath-expression”></xsl:template>

• <xsl:value-of select=“xpath-expression”/><xsl:copy-of select=“xpath-expression/node()”/>

• <xsl:call-template name=“template-name"/><xsl:apply-templates select=“xpath-expression”/><xsl:for-each select=“xpath-expression”></xsl:for-each>

• <xsl:if test=“expression=‘boolean’”></xsl:if><xsl:choose>

<xsl:when test=“expression”></xsl:when><xsl:otherwise></xsl:otherwise>

</xsl:choose>

• <xsl:sort select=“xpath-expression” order=“descending”/>

09/22/2008

Amy Liu & Brett Goodwin

Using { } in place of <xsl:value-of/><xsl:variable name=“default-page”>

index</xsl:variable>

<xsl:template match=“something”> <a> <xsl:attribute name=“href”> <xsl:value-of select=“path”/> <xsl:text>/</xsl:text> <xsl:value-of select=“$default-

page”/> </xsl:attribute> <xsl:value-of select="display-name"/> </a></xsl:template>

<xsl:variable name=“default-page”> index</xsl:variable>

<xsl:template match=“something”> <a href=“{path}/{$default-page}”> <xsl:value-of select="display-name"/> </a></xsl:template>

09/22/2008

Amy Liu & Brett Goodwin

Problem #1:Categorical Grouping…

Example Scenario:You have categorized a set of pages within

Cascade Server by utilizing Custom Metadata checkboxes.

Now, you would like to create a listing of all the categories along with the list of pages that belong to each category in alphabetical order for display on a “Campus Resources” page.

09/22/2008

[01grouping.xml]

Amy Liu & Brett Goodwin

1st Attempt:Easy-&-High-Maintenance Method

<xsl:template match=“/system-index-block”> <h1>Campus Resources</h1> <h3>Alumni</h3> <ul><xsl:apply-templates select=“//system-page[dynamic-metadata[name=‘Audience’]/value =

‘Alumni’]”><xsl:sort select=“display-name”/></xsl:apply-templates></ul> <h3>Current Students</h3> <ul><xsl:apply-templates select=“//system-page[dynamic-metadata[name=‘Audience’]/value = ‘Current

Students’]”><xsl:sort select=“display-name”/></xsl:apply-templates></ul> <h3>Prospective Students</h3> <ul><xsl:apply-templates select=“//system-page[dynamic-metadata[name=‘Audience’]/value = ‘Prospective

Students’]”><xsl:sort select=“display-name”/></xsl:apply-templates></ul> <h3>Visitors</h3> <ul><xsl:apply-templates select=“//system-page[dynamic-metadata[name=‘Audience’]/value =

‘Visitors’]”><xsl:sort select=“display-name”/></xsl:apply-templates></ul></xsl:template><xsl:template match=“system-page”> <li><xsl:value-of select=“display-name”/></li></xsl:template>

09/22/2008

[02grouping-attempt.xsl]

Amy Liu & Brett Goodwin

Muenchian Method!<xsl:key name=“unique-values” match=“//system-page/dynamic-metadata[name=‘Audience’]/value” use=“.”/><xsl:template match=“/system-index-block”> <h1>Campus Resources</h1> <xsl:apply-templates select=“//system-page/dynamic-metadata[name=‘Audience’]/value[generate-id()

=generate-id(key(‘unique-values’, .))]”> <xsl:sort select=“.”/> </xsl:apply-templates></xsl:template><xsl:template match=“value”> <xsl:variable name=“currentValue” select=“.”/> <h3><xsl:value-of select=“.”/></h3> <ul> <xsl:for-each select=“//system-page[dynamic-metadata[name=‘Audience’]/value=$currentValue]”> <xsl:sort select=“display-name”/> <li><xsl:value-of select=“display-name”/></li> </xsl:for-each> </ul></xsl:template>

09/22/2008

[03muenchian.xsl]

Amy Liu & Brett Goodwin

Problem #2:Truncating Content…

Example Scenario:Your users are now familiar with Cascade and

have created several blog posts within the system. You would like to set up some sort of landing page that features the latest blog posts.

09/22/2008

[04recent-blogs.xml]

Amy Liu & Brett Goodwin

1st Option:List 3 Latest Posts + Full Content

<xsl:template match=“system-index-block”> <xsl:apply-templates select=“//system-page”> <xsl:sort order=“descending” select=“start-date”/> </xsl:apply-templates></xsl:template>

<xsl:template match=“system-page”> <xsl:if test=“position() &lt; 4”> <h3><xsl:value-of select=“title”/></h3> <xsl:copy-of select=“page-xhtml/node()”/> </xsl:if></xsl:template>

09/22/2008

[05full-listing.xsl]

Amy Liu & Brett Goodwin

2nd Option:Truncate using Character Count

<xsl:variable name=“char-count” select=“216”/><xsl:template match=“system-index-block”> <xsl:apply-templates select=“//system-page”> <xsl:sort order=“descending” select=“start-date”/> </xsl:apply-templates></xsl:template>

<xsl:template match=“system-page”> <h3><xsl:value-of select=“title”/></h3> <p> < xsl:copy-of select=“substring(page-xhtml, 1, $char-count)”/> <xsl:text>...</xsl:text> </p> <p><a href=“{path}” title=“More”>More...</a></p></xsl:template>

09/22/2008

[06truncate-charcount.xsl]

Amy Liu & Brett Goodwin

3rd Option:Truncate after Whole Words

<xsl:variable name=“char-count” select=“216”/><xsl:template match=“system-index-block”> …</xsl:template><xsl:template match=“system-page”> <h3><xsl:value-of select=“title”/></h3> <p><xsl:call-template name=“parse”> <xsl:with-param name=“unrendered”> <xsl:variable name=“truncated-result”> <xsl:call-template name=“truncate-markup-text”> <xsl:with-param name=“unrendered” select=“page-

xhtml”/> </xsl:call-template> </xsl:variable> <xsl:value-of select=“substring-after($truncated-result,

‘]’)”/> </xsl:with-param> </xsl:call-template></p> <p><a href=“{path}” title=“More”>More...</a></p></xsl:template><xsl:template name=“truncate-markup-text”> <xsl:param name=“unrendered”/> <xsl:param name=“characters-chugged” select=“number(0)”/>

…</xsl:template><xsl:template name=“count-markup-text”> <xsl:param name=“content”/> <xsl:param name=“characters-chugged” select=“number(0)”/> <xsl:value-of select=“concat($characters-chugged + string-

length($content),‘]’)”/> …</xsl:template><xsl:template name=“get-trimmed-string”> <xsl:param name=“string”/> …</xsl:template><xsl:template name=“parse”> <xsl:param name=“unrendered”/> …</xsl:template><xsl:template name=“parseTagContent”> <xsl:param name=“tag”/> <xsl:param name=“tag-content”/> …</xsl:template>

09/22/2008

[07truncate-wordcount.xsl]

7 Templates382 Lines

15,167 Characters

Amy Liu & Brett Goodwin

EXSLT• Although XSLT lacks features like loops and mutable variables, it is considered

Turing-complete, meaning that given sufficient memory, XSLT can perform any calculation that can be performed by a modern computer program. However, this theoretical ability is often impractical.

• EXSLT is a community initiative to provide extensions to XSLT 1.0 and to partition them into functional groups that can be implemented on an á la carte basis. The EXSLT effort is an open one; anyone who wishes to contribute may do so. http://www.exslt.org/

• Many of the functions in EXSLT are simply shortcuts to equivalent behaviors that can be achieved using XSLT templates. For these functions, the EXSLT authors have provided XSLT templates that may be imported into existing style sheets. This approach offers the most portability, as all XSLT 1.0-compliant processors are able to correctly interpret the template and provide the functionality.

09/22/2008

Amy Liu & Brett Goodwin

3rd Option:Truncate using str:tokenize()

<xsl:variable name=“word-count” select=“37”/><xsl:template match=“system-index-block”> <xsl:apply-templates select=“//system-page”> <xsl:sort order=“descending” select=“start-date”/> </xsl:apply-templates></xsl:template><xsl:template match=“system-page”> <h3><xsl:value-of select=“title”/></h3> <p> <xsl:for-each select=“str:tokenize(string(page-xhtml))”> <xsl:if test=“position() &lt; $word-count”> <xsl:value-of select=“.”/><xsl:text> </xsl:text> </xsl:if> </xsl:for-each> <xsl:text>...</xsl:text> </p> <p><a href=“{path}” title=“More”>More...</a></p></xsl:template>

09/22/2008

[08exslt-tokenizer.xsl]

<xsl:stylesheet version=“1.0”xmlns:xsl=“http://www.w3.org/1999/XSL/Transform”xmlns:str=“http://exslt.org/strings”extension-element-prefixes=“str” >

Be sure to specify the extension namespace URI & use the extension-element-prefix!

Amy Liu & Brett Goodwin

Problem #3:Formatting Date & Time…

Example Scenario:Now that you have successfully truncated your

blog posts, the next item to tackle is to format and display the date/time that is associated with each post.

As you probably know, all date values within Cascade are represented in UNIX timestamp format (i.e., <start-date>1221165000000</start-date>).

09/22/2008

[04recent-blogs.xml]

Amy Liu & Brett Goodwin

Problem #3:Formatting Date & Time…

• If you were to attempt this calculation using only native XSLT 1.0, it will probably take about 304 lines or 10,345 characters.

• The EXSLT Dates-and-Times functions don’t have anything readily available for use with UNIX timestamps.

• Any other options?

09/22/2008

Amy Liu & Brett Goodwin

That’s right!Xalan Extensions

• Xalan is the XSLT processor that Cascade Server utilizes.• For those situations where you would like to augment the functionality

of XSLT with calls to a procedural language, Xalan-Java supports the creation and use of extension elements and extension functions.

• The Xalan XSLT processor can invoke almost any method in almost any Java™ class in the classpath. Doing so can improve performance, provide features like trigonometric functions that aren't available in XSLT, perform file I/O, talk to databases and network servers, or implement algorithms that are easy to write in the Java language but hard to write in XSLT.

• Typically, you'll resort to using Xalan extensions when you can't accomplish what you need using the existing XSLT or EXSL functions and need to write your own custom functions in Javascript or Java.

09/22/2008

Amy Liu & Brett Goodwin

Xalan Date Converter <p class=“date”> <xsl:value-of select=“date-

converter:convertMonth(number(start-date))”/>&#160;

<xsl:value-of select=“date-converter:convertDate(number(start-date))”/>,

<xsl:value-of select=“date-converter:convertYear(number(start-date))”/>

</p><h3><xsl:value-of select=“title”/></h3><p><xsl:for-each select=“str:tokenize(string(page-

xhtml))”> <xsl:if test=“position() &lt; $word-count”> <xsl:value-of select=“.”/> <xsl:text> </xsl:text> </xsl:if></xsl:for-each><xsl:text>...</xsl:text></p>

<xalan:component functions="convertDate" prefix="date-converter">

<xalan:script lang="javascript"> function convertMonth(date) { var months = new Array(13); months[0] = "January"; months[1] = "February"; months[2] = "March"; months[3] = "April"; months[4] = "May"; months[5] = "June"; months[6] = "July"; months[7] = "August"; months[8] = "September"; months[9] = "October"; months[10] = "November"; months[11] = "December"; var d = new Date(date); // Splits date into components var month = months[d.getMonth()]; return month; } convertDay(date) {…} convertDate(date) {…} convertYear(date) {…} convertTime(date) {…} </xalan:script></xalan:component>

09/22/2008

[09xalan-convertdate.xsl]

Amy Liu & Brett Goodwin

Velocity! The Non-XSLT Bonus

• Velocity is a Java-based template engine that Cascade Server will support starting with version 5.7

• It can be used to generate web pages, SQL, PostScript and other output from templates

• Velocity Template Language (VTL) should have a lower learning curve than XSLT for developers who are already familiar with traditional programming languages

• Utilizing VTL Formats, in some cases, can simplify the transformation code within Cascade

http://velocity.apache.org/engine/devel/user-guide.html

09/22/2008

Amy Liu & Brett Goodwin

Context Menu Comparison

XSLT Format<xsl:template match=“/”> <ul> <xsl:apply-templates select=“//system-

page | //system-folder”/> </ul></xsl:template><xsl:template match=“system-page | system-

folder”> <li> <a href=“{path}”> <xsl:value-of select=“name”/> </a> </li></xsl:template>

VTL Format<ul> #foreach ($child in $contentRoot.children) <li> <a href=“$child.getChild(“path”).text”> $child.getChild(“name”).text </a> </li> #end </ul>

09/22/2008

Amy Liu & Brett Goodwin09/22/2008