10. XPath Abbreviations Expression Description Nodename Selects named node / Selects from the root node (start of expression) or the current node // Selects any descendant of the root node (start of expression) or the current node . Selects the current node .. Selects the parent of the current node @ Selects attributes * Wildcard – matches any element node() Matches any node of any kind [ ] Brackets that contain a predicate, which is used to find a specific node
11.
12. List Numbering Goal: A client wants <ol>s in <fig>s to be uppercase-lettered, and sub-<ol>s to be lowercase-lettered Solution: <xsl:choose> <xsl:when test= "ancestor::*[contains(@class, ' topic/fig ')]" > <xsl:number format= "A" /> </xsl:when> <xsl:when test= "count(ancestor::*[contains(@class, ' topic/ol ')]) > 1" > <xsl:number format= "a" /> </xsl:when> <xsl:otherwise> <xsl:number/> </xsl:otherwise> </xsl:choose>
13. List Numbering Technique Note Instead of: <xsl:when test= "ancestor::*[contains(@class, ' topic/fig ')]" > We could say: <xsl:when test= "ancestor::fig" > But: That wouldn’t account for specialization!
14.
15. Trademarks and current() Goal: A client wants the trademark symbol to appear only on the first usage of each trademark Solution 1: <xsl:variable name= "trademark" select= "@trademark" /> <xsl:if test= "not(preceding::*[contains(@class, ' topic/tm ') and @trademark = $trademark)" > ... </xsl:if> Solution 2 (XPath 2.0): <xsl:if test= "not(preceding::*[contains(@class, ' topic/tm ') and @trademark = current()/@trademark)" > ... </xsl:if>
16.
17. Custom Functions Goal: A client wants to convert certain text strings to Title Case Solution: <xsl:stylesheet xmlns:xsl= "http://www.w3.org/1999/XSL/Transform" xmlns:ss= "http://www.suite-sol.com" version= "1.1" > <xsl:function name= "ss:first-upper-case" > <xsl:param name= "string" /> <xsl:value-of select= "concat(upper-case(substring($string, 1, 1)), lower-case(substring($string, 2)))" /> </xsl:function>
18. Custom Functions Goal: A client to convert certain text strings to Title Case Solution (continued): <xsl:function name= "ss:title-case" > <xsl:param name= "string" /> <xsl:choose> <xsl:when test= "contains($string, ' ')" > <xsl:value-of select= "concat(ss:first-upper-case(substring-before($string, ' ')), ' ', ss:title-case(substring-after($string), ' '))" /> </xsl:when> <xsl:otherwise> <xsl:value-of select= "ss:first-upper-case($string)" /> </xsl:otherwise> </xsl:choose> </xsl:function> <xsl:value-of select= "ss:title-case($stringToConvert)" />
19.
20. tokenize() Goal: A client wants to check for one outputclass (“border”) among many Challenge: There may also be a “borderless” outputclass, and the outputclass may appear among others (“border other”, “other border”, “otherA border otherB”) Solution 1: <xsl:if test= "(@outputclass = 'border') or starts-with(@outputclass, 'border ') or contains(@outputclass, ' border ') or (substring(@outputclass, string-length(@outputclass)-6, 7)= ' border')" > <xsl:attribute name= "border" > 1pt solid black </xsl:attribute> </xsl:if>
21. tokenize() Goal: A client wants to check for one outputclass (“border”) among many Challenge: There may also be a “borderless” outputclass, and the outputclass may appear among others (“border other”, “other border”, “otherA border otherB”) Solution 2 (XPath 2.0): <xsl:if test= "tokenize(@outputclass, ' ')[. = 'border']" > <xsl:attribute name= "border" > 1pt solid black </xsl:attribute> </xsl:if>
22.
23. Keys Trademark Revisited Goal: A client wants the trademark symbol to appear only on the first usage of each trademark, but doesn’t want to take the performance hit of searching through the entire document each and every time a <tm> is processed Solution: <xsl:key name= "tm" match= "*[contains(@class, ' topic/tm ')]" use= "@trademark" /> <xsl:if test= "generate-id(.) = generate-id(key('tm', @trademark)[1])" > … </xsl:if>
24.
25. Grouping Goal: A client wants to group child links by type stage1.xml: <linkpool class= "- topic/linkpool " > <link class= "- topic/link " role= "child" type= "concept" > <linktext class= "- topic/linktext " > Concept One </linktext> <desc class= "- topic/desc " > This is a concept topic. </desc> </link> <link class= "- topic/link " role= "child" type= "reference" > <linktext class= "- topic/linktext " > Reference One </linktext> <desc class= "- topic/desc " > This is a reference topic. </desc> </link> <link class= "- topic/link " role= "child" type= "concept" > <linktext class= "- topic/linktext " > Concept Two </linktext> <desc class= "- topic/desc " > This is another concept topic. </desc> </link> </linkpool>