1 / 66

4.1 Additional XSLT Features

4.1 Additional XSLT Features. XPath for arithmetics , cross-references, and string manipulation Generating text for content for attribute values Repetition, sorting and conditional processing Numbering document contents 4.2 Computing with XSLT. XPath : Arithmetics.

hayley
Télécharger la présentation

4.1 Additional XSLT Features

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 4.1 Additional XSLT Features • XPath for arithmetics, cross-references, and string manipulation • Generating text • for content • for attribute values • Repetition, sorting and conditional processing • Numbering document contents 4.2 Computing with XSLT XSLT: Additional features & Computing

  2. XPath: Arithmetics • Double-precision floating-point operators +, -, *, div, mod(same as %in Java) • e.g. 2.3 mod 1.1≈ 0.1 • Truncating numbers, and rounding up/to the closest int: floor(x), ceiling(x), round(x) • Formatting numbers as strings (e.g.): • format-number(-1.2534, "0.0") = "-1.3" • XSLT 1.0 function; uses Java DecimalFormat patterns XSLT: Additional features & Computing

  3. Aggregate Functions • Counting nodes • count(node-set) • and summing them as numbers • sum(node-set) • Example: • Average of observed temps below current node:sum(.//obs/@temperature) div count(.//obs) XSLT: Additional features & Computing

  4. Cross-referencing • Function idselects elements by their unique ID • NB: ID attributes must be declared in DTD(See an example later) • Examples: • id('sec:intro')selects the element with unique ID"sec:intro" • id('sec:intro')/auth[3]selects the thirdauthof the above element • id('sec1 sec2 sec3')selects 3 sections (with corresponding ID values) XSLT: Additional features & Computing

  5. String manipulation • Equality and inequality of strings with operators=and!= • "foo" = 'foo'; (NB alternative quotes) • "foo" != "Foo" • Testing for substrings: • starts-with("dogbert", "dog") = true() • contains("dogbert", "gbe") = true() • Concatenation (of two or more strings), • concat("dog", "bert") = "dogbert" XSLT: Additional features & Computing

  6. More XPath string functions • substring-before("ftp://a", "//") = substring-before("ftp://a", "/") = "ftp:" • substring-after("ftp://a", "/")= "/a" • string-length("dogbert")=7 • substring(string, start, length?): • substring("dogbert", 1, 3) = "dog" • substring("dogbert", 3) = "gbert" • translate(Str, Replaced, Replacing): • translate("doggy","dgo","Ssi") = "Sissy" XSLT: Additional features & Computing

  7. Generating Text • Insert text nodes with a computed value in the result:<xsl:value-of select="Expr" /> • if Expr gives a node-set, the value of the first nodein document order is used (in XSLT 2.0 all, space-separated) • Example: Transform elements like • <name alias="Bird"> <first>Charlie</first><last>Parker</last></name> • to the form • Charlie ("Bird") Parker XSLT: Additional features & Computing

  8. Computing generated text (2) • This can be specified by template rule <xsl:template match="name"> <xsl:value-of select="first" />("<xsl:value-of select="@alias" />") <xsl:value-of select="last" /> <xsl:text> </xsl:text></xsl:template> • xsl:textis seldom needed, but useful for including whitespace text XSLT: Additional features & Computing

  9. Attribute value templates • Expression string-values can be inserted in attribute values by enclosing expressions in braces{and} • Example: Transform source element <photo> <file>Mary.jpg</file> <size width="300"/> </photo>into form <img src="/images/Mary.jpg" width="300" /> XSLT: Additional features & Computing

  10. Attribute value templates (2) • This can be specified by template rule <xsl:template match="photo"> <img src="/images/{file}" width="{size/@width}" /> </xsl:template> • Expressions{file}and{size/@width} are evaluated in the context of the current node (the photoelement) XSLT: Additional features & Computing

  11. XSLT: Repetition • Nodes can be "pulled" from source for processing using <xsl:for-each select="Expr">Template </xsl:for-each> • Template is applied to the selected nodelist, each node in turn as the current() node • in document order, unless sorted using xsl:sort instructions (see later) XSLT: Additional features & Computing

  12. Example (of for-each) • Format the below document as HTML: <!DOCTYPE document [ <!ATTLIST section id ID #IMPLIED> ]><document> <title>The Joy of XML</title> <section id="Intro"><title>Getting Started</title> <name><first>Helen</first> <last>Brown</last></name> says that processing XML documents is fun. <name><first>Dave</first> <last>Dobrik</last></name> agrees. </section> <section><title>Family affairs</title> <name><first>Bob</first> <last>Brown</last></name> is the husband of <name><first>Helen</first> <last>Brown</last></name>. </section> <section><title>Finishing Up</title> As we discussed in <title-ref idref="Intro" />, processing XML documents is fun. </section></document> XSLT: Additional features & Computing

  13. Example: Table of contents • A table of contents can be formed of section titles: <xsl:template match="/"><HTML><HEAD> <TITLE><xsl:value-of select="document/title"/></TITLE></HEAD> <BODY> <H2>Table of Contents</H2> <OL> <!-- Pull each section title: --> <xsl:for-each select="//section/title"> <LI><xsl:apply-templates /></LI> </xsl:for-each> </OL> <!-- then process the sections: --> <xsl:apply-templates select="document/section"/> </BODY> </HTML></xsl:template> XSLT: Additional features & Computing

  14. Example (cont; Cross references) • Cross-refs can also be processed usingfor-each: <xsl:template match="title-ref"> <xsl:for-each select="id(@idref)"> <!-- just one selected --> Section (<xsl:value-of select="substring(title, 1, 8)" />...)</xsl:for-each></xsl:template> • With this rule the source fragment As we discussed in <title-ref idref="Intro"/> becomes As we discussed in Section (Getting …) XSLT: Additional features & Computing

  15. XSLT Sorting • Nodes can be processed in sorted order, by xsl:for-eachor xls:apply-templates, with <xsl:sort/> • controlled by attributes ofxsl:sort, like • select: expression for the sort key (default: ".") • data-type: "text"(default) or"number" • order:"ascending" (default) or "descending" • The first xsl:sort specifies the primary sort key, the second one the secondary sort key, and so on. XSLT: Additional features & Computing

  16. Possible to eliminate duplicates?Yes, but a bit tricky. See next Example (cont; Sorted index of names) • All names can be collected in a last-name-first-name order using the below template <H2>Index</H2> <UL> <xsl:for-each select="//name"> <xsl:sort select="last" /> <xsl:sort select="first" /> <LI><xsl:value-of select="last" />, <xsl:value-of select="first"/></LI> </xsl:for-each> </UL> • This creates an UL list with items <LI>Brown, Bob</LI> <LI>Brown, Helen</LI> <LI>Brown, Helen</LI> <LI>Dobrik, Dave</LI> XSLT: Additional features & Computing

  17. Conditional processing • A template can be instantiated or ignored with <xsl:iftest="BooleanExpr">Template</xsl:if> • Example: a comma-separated list of names: <xsl:template match="namelist/name"> <xsl:apply-templates/> <xsl:iftest="position() &lt; last()" >,</xsl:if></xsl:template> XSLT: Additional features & Computing

  18. An aside: Meaning of position() • Evaluation wrt the current node list. The above applied to <namelist><name>a</name><name>b</name></namelist> <namelist><name>c</name><name>d</name></namelist>by invocation<xsl:apply-templates select="//name" />yields"a,b,c,d" (← single node list); With invocation from<xsl:template match="namelist"> <xsl:apply-templates select="name" />we'd get"a,b"and"c,d" (Clever!) XSLT: Additional features & Computing

  19. Conditional processing (2) • A case construct ( switch in Java): <xsl:choose> <!-- The first 'when' whose test=true() is instantiated: --> <xsl:when test="Expr1"> … </xsl:when> <xsl:when test="Expr2"> … </xsl:when> … <!-- If no 'when' applies, an optional 'otherwise' is instantiated: --> <xsl:otherwise> … </xsl:otherwise> </xsl:choose> XSLT: Additional features & Computing

  20. Example (cont; Eliminating duplicate names) • Only the current() node accessible in current node list • but can refer to nodes in the source tree • Process just the first one of duplicate names: <xsl:for-each select="//name"> <xsl:sort select="last"/><xsl:sort select="first" /> <xsl:if test="not( preceding::name[first=current()/first and last=current()/last] )"> <LI><xsl:value-of select="last" />, <xsl:value-of select="first"/></LI></xsl:if> </xsl:for-each> XSLT: Additional features & Computing

  21. Numbering Document Contents • Formatted numbers can be generated using <xsl:number/> • by the position of the current node in the source tree • or by an explicit value="ArithmExpr" • nodes to be counted specified by a count pattern • supports common numbering schemes : single-level, hierarchical, and sequential through levels • Typical cases in following examples • (Complete specification is rather complex) • Example 1: Numbering list items XSLT: Additional features & Computing

  22. item item item ol 1. 2. 3. apricot banana coconut Generating numbers: Example 1 • <xsl:template match="ol/item"> <!-- default: count similar siblings (items) --><xsl:number format="1. "/> <xsl:apply-templates/><xsl:template> apricot banana coconut XSLT: Additional features & Computing

  23. Generating numbers: Example 2 • Hierarchical numbering (1, 1.1, 1.1.1, 1.1.2, …) for titles of chapters, titles of their sections, and titles of subsections: <xsl:template match="title"><xsl:number level="multiple" count="chap | sect | subsect" format="1.1 "/> <xsl:apply-templates/></xsl:template> XSLT: Additional features & Computing

  24. subsect title title title title chap part Sweets 1 1.1 1.1.1 2 Cherry chap Berries sect Generating numbers: Example 2 . . . Vegetables Sweets Berries Cherry Vegetables . . . XSLT: Additional features & Computing

  25. Example 2: Variation • As above, but number titles within appendices with A, A.1, A.1.1, B.1 etc: <xsl:template match="appendix//title"><xsl:number level="multiple" count="appendix | sect | subsect" format="A.1 "/> <xsl:apply-templates/></xsl:template> XSLT: Additional features & Computing

  26. appendix subsect title title title title part Sweets A A.1 A.1.1 B Cherry Berries sect Example 2: Variation appendix . . . Vegetables Sweets Berries Cherry Vegetables . . . XSLT: Additional features & Computing

  27. Generating numbers: Example 3 • Sequential numbering of noteswithinchapters:(more precisely: starting anew at the start of any chapter) <xsl:template match="note"><xsl:number level="any" from="chap" format="(1) "/> <xsl:apply-templates/></xsl:template> XSLT: Additional features & Computing

  28. chap note note note note Yes! (1) (2) (3) (1) Yes! No! Perhaps? OK Perhaps? No! sect Ex 3: Sequential numbering from chap chap . . . OK . . . XSLT: Additional features & Computing

  29. 4.2 Computing with XSLT • XSLT is a declarative rule-based language • for XML transformations • Could we use it for general computing? • What is the exact computational power of XSLT? • We've seen some programming-like features: • iteration over source nodes (xsl:for-each) • XSLT 2.0 supports iteration over arbitrary sequences • conditional evaluation (xsl:ifandxsl:choose) XSLT: Additional features & Computing

  30. Computing with XSLT • Further programming-like features: • variables (names bound to non-updatable values): <xsl:for-each select="//name"><xsl:variable name="LAndF" select="concat(last, ', ', first)"/>... ...</xsl:for-each> • callablenamed templateswithparameters:<xsl:call-template name="process-name"> <xsl:with-param name="pname" select="$LAndF" /> </xsl:call-template> XSLT: Additional features & Computing

  31. Result Tree Fragments • Result tree fragments built by templates can be stored, too:<xsl:variable name="fooBar"> <FOO>BAR</FOO></xsl:variable> • They can only be used as string valuessubstring($fooBar, 2, 2) = "AR" • or inserted in the result:<xsl:copy-of select="$fooBar" /> • (XSLT 2.0 allows unlimited accessing of (computed) sequences, e.g., with location paths) XSLT: Additional features & Computing

  32. Visibility of Variable Bindings • The binding is visible in following siblings of xsl:variable,and in their descendants: <xsl:for-each select="//name"><xsl:variable name="LAndF" select="concat(last, ', ', first)"/>... <xsl:call-template name="process-name"> <xsl:with-param name="pname" select="$LAndF" /> </xsl:call-template> ...</xsl:for-each><TABLE> . . . </TABLE> XSLT: Additional features & Computing

  33. A Real-Life Example • We used LaTeX to format an XML article. For this, we needed to map source table structures<tgroup cols="3"> ... </tgroup>to corresponding LaTeX environments:\begin{tabular}{lll} %3 left-justified cols ... \end{tabular} • How to do this? XSLT: Additional features & Computing

  34. Possible solution (for up to 4 columns) <xsl:template match="tgroup"> \begin{tabular}{l }<xsl:apply-templates /> \end{tabular} </xsl:template> • OK, but inelegant! • How to support arbitrarily many columns? <xsl:if test="@cols > 1">l</xsl:if ><xsl:if test="@cols > 2">l</xsl:if ><xsl:if test="@cols > 3">l</xsl:if> XSLT: Additional features & Computing

  35. More General Solution (1/2) • Pass the column-count to a named template which generates the requested number of ‘l’s:<xsl:template match="tgroup"> \begin{tabular}{ } <xsl:apply-templates /> \end{tabular} </xsl:template> <xsl:call-template name="gen-cols"> <xsl:with-param name="count" select="@cols" /> <xsl:with-param name="symb" select="'l'" /> </xsl:call-template> XSLT: Additional features & Computing

  36. formal parameters Solution 2/2: Recursive gen-cols <xsl:template name="gen-cols"> <xsl:param name="count" /> <xsl:param name="symb" /> <xsl:if test="$count > 0"> <xsl:value-of select="$symb" /> <xsl:call-template name="gen-cols"> <xsl:with-param name="count" select="$count - 1" /> <xsl:with-param name="symb" select="$symb" /> </xsl:call-template> </xsl:if> </xsl:template> XSLT: Additional features & Computing

  37. Iteration in XSLT 2.0 • XSLT 2.0 is more convenient, by allowing iteration over generated sequences, too:<xsl2:template match="tgroup">\begin{tabular}{<xsl2:for-each select="1 to @cols"> <xsl2:text>l</xsl2:text> </xsl2:for-each>} \end{tabular} </xsl2:template> XSLT: Additional features & Computing

  38. StylesheetParameters • Stylesheetcangetparamsfromcommandline, orthrough JAXP withTransformer.setParameter(name, value): <xsl:transform ... > <xsl:output method="text" /> <xsl:param name="In" select="0" /><xsl:template match="/"> <xsl:value-of select="2*$In"/> </xsl:template> </xsl:transform> $ java -jar saxon.jar dummy.xml double.xslt In=120 240 default value XSLT: Additional features & Computing

  39. Generating XML TestCases • XSLT is handy for generating XML test cases • An XSLT 2.0 script to generate n sections: <!DOCTYPE xsl:transform [ <!ENTITY CONT "<xsl:comment>Lengthy XML fragment (excluded)</xsl:comment>" > ]> <xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:param name="n" select="10"/> XSLT: Additional features & Computing

  40. XSLT 2.0 scriptcontinues <xsl:template match="/"> <doc> <title>A doc with <xsl:value-of select="$n"/> sections</title> <xsl:for-each select="1 to $n"> <section> <title>Section number <xsl:value-of select="." /> </title> &CONT; </section> </xsl:for-each> </doc> </xsl:template> </xsl:transform> Extensions in XPath 2.0, to generate and access non-nodesequences XSLT: Additional features & Computing

  41. Invoking the Script • The script can be used as the required (dummy) input document: $ saxon9 genTest-iter.xsltgenTest-iter.xslt n=1000 • XSLT 1.0 does not support iteration over generated sequences ; In XSLT 1.0 we must recurse: <doc> <title>A doc with <xsl:value-of select="$n"/> sections</title> <xsl:call-template name ="genSecs"> <xsl:with-param name="count" select="1"/> </xsl:call-template> </doc> XSLT: Additional features & Computing

  42. Tail-recursivegenSecstemplate <xsl:template name="genSecs"> <xsl:param name="count" /> <xsl:if test="$count &lt;= $n"> <section><title>Section <xsl:value-of select="$count"/></title> &CONT; </section> <!-- Create the rest sections: --> <xsl:call-template name="genSecs"> <xsl:with-param name="count" select="$count + 1" /> </xsl:call-template> </xsl:if> </xsl:template> XSLT: Additional features & Computing

  43. Problem with Tail-Recursion • The depth of tail-recursion is linear. This may lead to problems with large n (say, above a few thousands): • Saxon:StackOverflowError • xsltproc: "A potential infinite template recursion was detected. You can adjust xsltMaxDepth (--maxdepth) in order to raise the maximum number of nested template calls and variables/params (currently set to 3000)." • Solution: Enter Algorithm Design! SDPL 2008 XSLT: Additional features & Computing 43

  44. Apply Divide-and-Conquer • Split the problem/task in (equal-sized) sub-problems, and solve them recursively • To generate secs$first, ..., $last, compute their mid-point $mid, and generate the halves $first, ..., $mid, and $mid+1, ..., $last: • <xsl:call-templatename="genSecsDC"> • <xsl:with-param name="first" select="1"/> • <xsl:with-param name="last" select="$n"/> • </xsl:call-template> SDPL 2008 XSLT: Additional features & Computing 44

  45. Divide-and-ConquergenSecstemplate <xsl:templatename="genSecsDC"> <xsl:paramname="first" /> <xsl:paramname="last" /> <xsl:choose> <xsl:when test="$first = $last"> <!-- base case --> <section> <title>Section number <xsl:value-of select="$first"/></title> &CONT; </section> </xsl:when> <!-- otherwise recurse: --> SDPL 2008 XSLT: Additional features & Computing 45

  46. Divide&ConquergenSecs (cont.) <xsl:when test="$first &lt; $last"> <xsl:variable name="mid" select="floor(($first + $last) div 2)" /> <xsl:call-template name="genSecsDC"> <xsl:with-param name="first" select="$first" /> <xsl:with-param name="last" select="$mid" /> </xsl:call-template> <xsl:call-template name="genSecsDC"> <xsl:with-param name="first" select="$mid+1" /> <xsl:with-param name="last" select="$last" /> </xsl:call-template> </xsl:when> </xsl:choose> </xsl:template> SDPL 2008 XSLT: Additional features & Computing 46

  47. Balanced D&C Recursion Tree (draw it!) SDPL 2008 XSLT: Additional features & Computing 47

  48. Effect of Divide-and-Conquer • The depth of balanced divide-and-conquer recursion is logarithmic only • E.g., log(10^6) ~ 20, log(10^9) ~ 30 • Piece of cake! • Divide-and-conquer doubles the number of recursive calls above. Does this make a big difference? • No; See next SDPL 2008 XSLT: Additional features & Computing 48

  49. XSLT 1.0 execution times $ timesaxongenTest-tailrec.xsltgenTest-tailrec.xslt n=1000000 > /dev/null real 0m12.808s user 0m12.924s sys 0m0.104s $ timesaxongenTest-tailrec.xsltgenTest-dc.xslt n=1000000 > /dev/null real 0m13.871s (~8% more) user 0m14.016s sys 0m0.088s Div&Conquerscript SDPL 2008 XSLT: Additional features & Computing 49

  50. Iteration vs Tail-recursion vs Div&Conq Some XSLT 2.0 execution times: $ time saxon9 dummy.xmlgenTest-iter.xslt n=1000000 real 0m11.277s user 0m10.118s $ time saxon9 dummy.xmlgenTest-tailrec.xslt n=1000000 real 0m24.803s (~120% morethaniteratively) user 0m24.658s $ time saxon9 dummy.xmlgenTest-dc.xslt n=1000000 real 0m29.779s (~164% morethaniteratively) user 0m30.178s SDPL 2008 XSLT: Additional features & Computing 50

More Related