Carrot<br />An appetizing hybrid of XQuery and XSLT<br />Evan Lenz<br />Software Developer, Community<br />MarkLogic Corpo...
On reinventing the wheel<br />XSLT-UK 2001<br />“XQuery: Reinventing the wheel?”<br />http://xmlportfolio.com/xquery.html<...
Disclaimer<br />My own personal project& opinions<br />
Praises for XSLT	<br />Template rules are really elegant and powerful<br />It’s mature in its set of features<br />Powerfu...
Praises for XQuery<br />Concise syntax<br />Highly composable syntax<br />An element constructor is an expression<br />So ...
Gripes about XSLT<br />Two layers of syntax, which can’t be freely composed<br />You can’t nest an instruction inside an e...
Gripes about XQuery<br />Conflation of modules and namespaces<br />Don’t like being forced to use namespace URIs<br />Dist...
A lot in common<br />The same data model (XPath 2.0)<br />Much of the same syntax (XPath 2.0)<br />
Feeling boxed-in<br />XSLT’s lack of composability<br />XQuery’s lack of template rules<br />Don’t like having to pick bet...
YAASFXSLT<br />“Yet Another Alternative Syntax For XSLT”<br />Sam Wilmott’s RXSLT<br />http://www.wilmott.ca/rxslt/rxslt.h...
Actually: “Carrot”<br />More than just an alternative syntax<br />Carrot combines:<br />the friendly syntax and composabil...
Motivation & inspiration<br />My boxed-in feelings<br />OH: “I will never write code in XML.”<br />James Clark’s element c...
Overall design approach<br />95% of semantics defined by reference to XQuery and XSLT<br />90% of syntax defined by refere...
Haskell similarities<br />Haskell defines functions using equations:<br />foo = "bar"<br />Carrot defines variables, funct...
Haskell similarities<br />Haskell defines functions using equations:<br />foo = "bar"<br />Carrot defines variables, funct...
Intro by example<br />
Intro by example<br />A rule definition in XSLT:<br /><xsl:template match="para">  <p>    <xsl:apply-templates/>  </p></xs...
Intro by example<br />A rule definition in XSLT:<br /><xsl:template match="para">  <p>    <xsl:apply-templates/>  </p></xs...
Intro by example<br />A rule definition in XSLT:<br /><xsl:template match="para">  <p>    <xsl:apply-templates/>  </p></xs...
Intro by example<br />A rule definition in XSLT:<br /><xsl:template match="para"><p>    <xsl:apply-templates/></p></xsl:te...
Intro by example<br />A rule definition in XSLT:<br /><xsl:template match="para">  <p><xsl:apply-templates/>  </p></xsl:te...
Intro by example<br />This:<br />	^()<br />Is short for this:<br />	^(node())<br />Just as, in XSLT, this:<br /><xsl:apply...
Intro by example<br />Another rule definition in Carrot:<br />	^toc(section) := <li>{ ^toc() }</li>;<br />The same rule de...
Intro by example<br />Another rule definition in Carrot:<br />	^toc(section) := <li>{ ^toc() }</li>;<br />The same rule de...
Intro by example<br />Another rule definition in Carrot:<br />	^toc(section) := <li>{ ^toc() }</li>;<br />The same rule de...
Intro by example<br />Another rule definition in Carrot:<br />	^toc(section) := <li>{ ^toc() }</li>;<br />The same rule de...
Intro by example<br />Another rule definition in Carrot:<br />	^toc(section) := <li>{ ^toc() }</li>;<br />The same rule de...
The identity transform<br />In Carrot:<br />	^(@*|node()) := copy{ ^(@*|node()) };<br />In XSLT:<br /><xsl:template match=...
The identity transform<br />In Carrot:<br />	^(@*|node()) := copy{ ^(@*|node()) };<br />In XSLT:<br /><xsl:template match=...
The identity transform<br />In Carrot:<br />	^(@*|node()) := copy{ ^(@*|node()) };<br />In XSLT:<br /><xsl:template match=...
The identity transform<br />In Carrot:<br />	^(@*|node()) := copy{ ^(@*|node()) };<br />In XSLT:<br /><xsl:template match=...
Note the asymmetry<br />This definition is illegal (missing pattern):<br />	^() := <foo/>;<br />Just as this template rule...
An XSLT example<br /><xsl:transform version="2.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform">   <xsl:template match="...
An XSLT example<br /><xsl:transform version="2.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform">   <xsl:template match="...
The equivalent in Carrot<br />^(/) := <html>   <head>{ /doc/title   }</head>   <body>{ ^(/doc/para) }</body> </html>;^(par...
The equivalent in Carrot<br />^(/) := <html>   <head>{ /doc/title   }</head>   <body>{ ^(/doc/para) }</body> </html>;^(par...
Carrot expressions<br />
Carrot expressions<br />Same as an expression in XQuery, with these additions:<br />rulesetinvocations — ^mode(nodes) <br ...
1. Ruleset invocations<br />In XSLT, each mode can be thought of as the name of a polymorphic function<br />The syntax of ...
1. Ruleset invocations<br />“ruleset” == “mode”<br />In Carrot:<br />	^myMode(myExpr)<br />In XSLT:<br /><xsl:apply-templa...
1. Ruleset invocations<br />“ruleset” == “mode”<br />In Carrot:<br />	^myMode(myExpr)<br />In XSLT:<br /><xsl:apply-templa...
1. Ruleset invocations<br />“ruleset” == “mode”<br />In Carrot:<br />	^myMode(myExpr)<br />In XSLT:<br /><xsl:apply-templa...
2. Shallow copy constructors<br />In Carrot: copy{…}<br />In XSLT:<xsl:copy>…</xsl:copy><br />
2. Shallow copy constructors<br />In Carrot: copy{…}<br />In XSLT:<xsl:copy>…</xsl:copy><br />Why extend XQuery here?<br /...
3. Text node literals<br />In Carrot:`my text node`<br />
3. Text node literals<br />In Carrot:`my text node`<br />In XSLT (a literal text node):my text node<br />
3. Text node literals<br />In Carrot:`my text node`<br />In XSLT (a literal text node):my text node<br />In XQuery (dynami...
3. Text node literals<br />In Carrot:`my text node`<br />In XSLT (a literal text node):my text node<br />In XQuery (dynami...
3. Text node literals<br />Consider an example:<br /><xsl:template match="/doc">  <result>    <xsl:apply-templates mode="f...
3. Text node literals<br />Consider an example:<br /><xsl:template match="/doc">  <result>    <xsl:apply-templates mode="f...
3. Text node literals<br />Consider an example:<br /><xsl:template match="/doc">  <result>    <xsl:apply-templates mode="f...
3. Text node literals<br />Consider an example:<br /><xsl:template match="/doc">  <result>    <xsl:apply-templates mode="f...
3. Text node literals<br />Same example, rewritten “naturally” in Carrot:<br />^(/doc) := <result>{^file-name(.),         ...
3. Text node literals<br />Same example, rewritten “naturally” in Carrot:<br />^(/doc) := <result>{^file-name(.),         ...
3. Text node literals<br />Same example, rewritten “naturally” in Carrot:<br />^(/doc) := <result>{^file-name(.),         ...
3. Text node literals<br />Same example, rewritten “naturally” in Carrot:<br />^(/doc) := <result>{^file-name(.),         ...
3. Text node literals<br />Sequences of atomic values have spaces added upon conversion to a text node<br />Various fixes,...
3. Text node literals<br />Note the imbalance:<br />Returning a text node is more concise in XSLT than in XQuery (!)<br />...
3. Text node literals<br />Rewritten properly in Carrot:<br />^(/doc) := <result>{^file-name(.),                    ^file-...
Expression semantics<br />Same as XQuery!<br />With this exception (remember the earlier gripe):<br />Namespace attribute ...
Carrot definitions<br />
A Carrot module<br />Consists of a set of unordered definitions<br />Three kinds of definitions:<br />Global variables<br ...
Global variables<br />In Carrot:<br />$foo := "a string value";<br />
Global variables<br />In Carrot:<br />$foo := "a string value";<br />Equivalent to this XQuery:<br />declare variable $foo...
Global variables<br />In Carrot:<br />$foo := "a string value";<br />Equivalent to this XQuery:<br />declare variable $foo...
Functions<br />In Carrot:<br />my:foo() := "return value";<br />
Functions<br />In Carrot:<br />my:foo()                 := "return value";my:bar($str as xs:string)            as xs:strin...
Functions<br />In Carrot:<br />my:foo()                 := "return value";my:bar($str as xs:string)            as xs:strin...
Functions<br />In Carrot:<br />my:foo() := "return value";my:bar($str as xs:string)            as xs:string:= upper-case($...
Rule definitions<br />In Carrot:<br />^foo(*) := "return value";<br />Equivalent to this XSLT:<br /><xsl:template match="*...
Rule definitions<br />In Carrot:<br />^foo(*) := "return value";<br />Equivalent to this XSLT:<br /><xsl:template match="*...
Rule definitions<br />In Carrot:<br />^foo(*) := "return value";<br />Equivalent to this XSLT:<br /><xsl:template match="*...
Rule definitions<br />In Carrot:<br />^foo(*) := "return value";<br />Equivalent to this XSLT:<br /><xsl:template match="*...
Rule parameters<br />In Carrot:<br />^foo(* ; $str as xs:string) := concat($str, .);<br />
Rule parameters<br />In Carrot:<br />^foo(* ; $str as xs:string) := concat($str, .);<br />Equivalent to this XSLT:<br /><x...
Rule parameters<br />In Carrot:<br />^foo(* ; $str as xs:string) := concat($str, .);<br />Equivalent to this XSLT:<br /><x...
Rule parameters<br />In Carrot:<br />^foo(* ; tunnel $str as xs:string) := concat($str, .);<br />Equivalent to this XSLT:<...
Conflict resolution<br />Same as XSLT<br />Import precedence first<br />Then priority<br />
Explicit priorities<br />In Carrot:<br />^author-listing( author[1]      ) 1 :=           ^();^author-listing( author     ...
Explicit priorities<br />In Carrot:<br />^author-listing( author[1]      ) 1 :=           ^();^author-listing( author     ...
Explicit priorities<br />In Carrot:<br />^author-listing( author[1]      ) 1:=           ^();^author-listing( author      ...
Multiple modes<br />In Carrot:<br />^foo|bar(*) := `result`;<br />Equivalent to this XSLT:<br /><xsl:template mode="foo ba...
Multiple modes<br />In Carrot:<br />^foo|bar(*) := `result`;<br />Equivalent to this XSLT:<br /><xsl:template mode="foo ba...
Why I like composability<br />A couple of examples<br />
Pipelines are easier<br />A typical pipeline approach in XSLT:<br /><xsl:variable name="stage1-result">  <xsl:apply-templa...
Pipelines are easier<br />A typical pipeline approach in XSLT:<br /><xsl:variable name="stage1-result">  <xsl:apply-templa...
Fewer features needed<br />XSLT 2.1/3.0 promises to add some convenience features, like:<br /><xsl:copy select="foo">…</xs...
What about feature X?<br />
Two instruction categories<br />XSLT instructions that aren’t needed<br /><xsl:for-each> - Use for expressions (or mapping...
Top-level elements<br />Imports and includes<br />import navigation.crt;include widgets.crt;<br />Top-level parameters<br ...
Implementation strategy<br />
Compile to XSLT 2.0<br />1:1 module mapping<br />Each Carrot module compiles to an XSLT 2.0 module<br />Carrot can include...
Steps to implementation<br />Generate a parser<br />Create a BNF grammar for Carrot<br />Hand-convert the EBNF grammar for...
Project goals<br />At this point, just explore the raw ideas (and share them)<br />Solicit feedback<br />Placeholder for n...
Future possibilities<br />
XML-oriented browser scripting<br />XQIB<br />Saxon-CE<br />Carrot, or something like it, could make XSLT more palatable t...
W3C activity <br />Provide seeds for ideas in the XSL/XQuery WGs?<br />Carrot will grow with XPath/XQuery/XSLT<br />
Mode merging<br />Random XSLT feature idea: invoke more than one mode<br /><xsl:apply-templates mode="foo bar"/><br />In C...
Questions?<br />
Upcoming SlideShare
Loading in...5
×

Carrot: An appetizing hybrid of XQuery and XSLT

1,243

Published on

Balisage paper link: http://www.balisage.net/Proceedings/vol7/html/Lenz01/BalisageVol7-Lenz01.html

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,243
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
12
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Carrot: An appetizing hybrid of XQuery and XSLT

  1. 1. Carrot<br />An appetizing hybrid of XQuery and XSLT<br />Evan Lenz<br />Software Developer, Community<br />MarkLogic Corporation<br />
  2. 2. On reinventing the wheel<br />XSLT-UK 2001<br />“XQuery: Reinventing the wheel?”<br />http://xmlportfolio.com/xquery.html<br />
  3. 3. Disclaimer<br />My own personal project& opinions<br />
  4. 4. Praises for XSLT <br />Template rules are really elegant and powerful<br />It’s mature in its set of features<br />Powerful modularization features (<xsl:import>)<br />
  5. 5. Praises for XQuery<br />Concise syntax<br />Highly composable syntax<br />An element constructor is an expression<br />So you can write things like: foo/<bar/><br />
  6. 6. Gripes about XSLT<br />Two layers of syntax, which can’t be freely composed<br />You can’t nest an instruction inside an expression<br />E.g., you can’t apply templates inside an XPath expression<br />Verbose syntax<br />In general<br />In particular, for function definitions and parameter-passing<br />
  7. 7. Gripes about XQuery<br />Conflation of modules and namespaces<br />Don’t like being forced to use namespace URIs<br />Distinction between main and library modules<br />You can’t reuse a main module<br />Reuse requires refactoring<br />Lack of a distinction between:<br />the default namespace for XPath, and<br />the default namespace for element constructors<br />No template rules!<br />
  8. 8. A lot in common<br />The same data model (XPath 2.0)<br />Much of the same syntax (XPath 2.0)<br />
  9. 9. Feeling boxed-in<br />XSLT’s lack of composability<br />XQuery’s lack of template rules<br />Don’t like having to pick between two languages all the time<br />Solution: add a third one. ;-)<br />And I’m calling it…<br />
  10. 10. YAASFXSLT<br />“Yet Another Alternative Syntax For XSLT”<br />Sam Wilmott’s RXSLT<br />http://www.wilmott.ca/rxslt/rxslt.html<br />Paul Tchistopolskii’sXSLScript<br />http://markmail.org/message/niumiluelzho6bmt<br />XSLTXT<br />http://savannah.nongnu.org/projects/xsltxt<br />
  11. 11. Actually: “Carrot”<br />More than just an alternative syntax<br />Carrot combines:<br />the friendly syntax and composability of XQuery expressions<br />the power and flexibility of template rules in XSLT<br />A “host language” for XQuery expressions<br />
  12. 12. Motivation & inspiration<br />My boxed-in feelings<br />OH: “I will never write code in XML.”<br />James Clark’s element constructor proposal back in 2001<br />http://www.jclark.com/xml/construct.html<br />Haskell<br />
  13. 13. Overall design approach<br />95% of semantics defined by reference to XQuery and XSLT<br />90% of syntax defined by reference to XQuery<br />
  14. 14. Haskell similarities<br />Haskell defines functions using equations:<br />foo = "bar"<br />Carrot defines variables, functions, and rules similarly:<br />$foo := "bar";<br />my:foo() := "bar";<br />^foo(*) := "bar";<br />
  15. 15. Haskell similarities<br />Haskell defines functions using equations:<br />foo = "bar"<br />Carrot defines variables, functions, and rules similarly:<br />$foo := "bar";<br />my:foo() := "bar";<br />^foo(*) := "bar";<br />Everything on the RHS is an XQuery expression<br />(plus a few extensions)<br />
  16. 16. Intro by example<br />
  17. 17. Intro by example<br />A rule definition in XSLT:<br /><xsl:template match="para"> <p> <xsl:apply-templates/> </p></xsl:template><br />
  18. 18. Intro by example<br />A rule definition in XSLT:<br /><xsl:template match="para"> <p> <xsl:apply-templates/> </p></xsl:template><br />A rule definition in Carrot:<br /> ^(para) := <p>{^()}</p>;<br />
  19. 19. Intro by example<br />A rule definition in XSLT:<br /><xsl:template match="para"> <p> <xsl:apply-templates/> </p></xsl:template><br />A rule definition in Carrot:<br /> ^(para) := <p>{^()}</p>;<br />
  20. 20. Intro by example<br />A rule definition in XSLT:<br /><xsl:template match="para"><p> <xsl:apply-templates/></p></xsl:template><br />A rule definition in Carrot:<br /> ^(para) := <p>{^()}</p>;<br />
  21. 21. Intro by example<br />A rule definition in XSLT:<br /><xsl:template match="para"> <p><xsl:apply-templates/> </p></xsl:template><br />A rule definition in Carrot:<br /> ^(para) := <p>{^()}</p>;<br />
  22. 22. Intro by example<br />This:<br /> ^()<br />Is short for this:<br /> ^(node())<br />Just as, in XSLT, this:<br /><xsl:apply-templates/><br />Is short for this:<br /><xsl:apply-templates select="node()"/><br />
  23. 23. Intro by example<br />Another rule definition in Carrot:<br /> ^toc(section) := <li>{ ^toc() }</li>;<br />The same rule definition in XSLT:<br /><xsl:template match="section" mode="toc"> <li> <xsl:apply-templates mode="toc"/> </li></xsl:template><br />
  24. 24. Intro by example<br />Another rule definition in Carrot:<br /> ^toc(section) := <li>{ ^toc() }</li>;<br />The same rule definition in XSLT:<br /><xsl:templatematch="section" mode="toc"> <li> <xsl:apply-templates mode="toc"/> </li></xsl:template><br />
  25. 25. Intro by example<br />Another rule definition in Carrot:<br /> ^toc(section) := <li>{ ^toc() }</li>;<br />The same rule definition in XSLT:<br /><xsl:template match="section" mode="toc"> <li> <xsl:apply-templates mode="toc"/> </li></xsl:template><br />
  26. 26. Intro by example<br />Another rule definition in Carrot:<br /> ^toc(section) := <li>{ ^toc() }</li>;<br />The same rule definition in XSLT:<br /><xsl:template match="section" mode="toc"><li> <xsl:apply-templates mode="toc"/></li></xsl:template><br />
  27. 27. Intro by example<br />Another rule definition in Carrot:<br /> ^toc(section) := <li>{ ^toc() }</li>;<br />The same rule definition in XSLT:<br /><xsl:template match="section" mode="toc"> <li> <xsl:apply-templates mode="toc"/> </li></xsl:template><br />
  28. 28. The identity transform<br />In Carrot:<br /> ^(@*|node()) := copy{ ^(@*|node()) };<br />In XSLT:<br /><xsl:template match="@* | node()"> <xsl:copy><xsl:apply-templates select="@* | node()"/> </xsl:copy></xsl:template><br />
  29. 29. The identity transform<br />In Carrot:<br /> ^(@*|node()) := copy{ ^(@*|node()) };<br />In XSLT:<br /><xsl:template match="@* | node()"> <xsl:copy><xsl:apply-templates select="@* | node()"/> </xsl:copy></xsl:template><br />
  30. 30. The identity transform<br />In Carrot:<br /> ^(@*|node()) := copy{ ^(@*|node()) };<br />In XSLT:<br /><xsl:template match="@* | node()"> <xsl:copy><xsl:apply-templates select="@* | node()"/> </xsl:copy></xsl:template><br />
  31. 31. The identity transform<br />In Carrot:<br /> ^(@*|node()) := copy{ ^(@*|node()) };<br />In XSLT:<br /><xsl:template match="@* | node()"> <xsl:copy><xsl:apply-templates select="@* | node()"/> </xsl:copy></xsl:template><br />
  32. 32. Note the asymmetry<br />This definition is illegal (missing pattern):<br /> ^() := <foo/>;<br />Just as this template rule is illegal:<br /> <xsl:template match=""><foo/></xsl:template><br />However, when invoking, you can omit the argument:<br />^()<br />Just as in XSLT:<br /><xsl:apply-templates/><br />
  33. 33. An XSLT example<br /><xsl:transform version="2.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <head><xsl:copy-of select="/doc/title"/> </head><body><xsl:apply-templates select="/doc/para"/></body></html></xsl:template><xsl:template match="para"><p><xsl:apply-templates/></p></xsl:template></xsl:stylesheet><br />
  34. 34. An XSLT example<br /><xsl:transform version="2.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <head><xsl:copy-of select="/doc/title"/> </head><body><xsl:apply-templates select="/doc/para"/></body></html></xsl:template><xsl:template match="para"><p><xsl:apply-templates/></p></xsl:template></xsl:stylesheet><br />
  35. 35. The equivalent in Carrot<br />^(/) := <html> <head>{ /doc/title }</head> <body>{ ^(/doc/para) }</body> </html>;^(para) := <p>{ ^() }</p>;<br />
  36. 36. The equivalent in Carrot<br />^(/) := <html> <head>{ /doc/title }</head> <body>{ ^(/doc/para) }</body> </html>;^(para) := <p>{ ^() }</p>;<br />
  37. 37. Carrot expressions<br />
  38. 38. Carrot expressions<br />Same as an expression in XQuery, with these additions:<br />rulesetinvocations — ^mode(nodes) <br />shallow copy{…}constructors<br />text node literals — `my text node` <br />
  39. 39. 1. Ruleset invocations<br />In XSLT, each mode can be thought of as the name of a polymorphic function<br />The syntax of Carrot makes this explicit<br />
  40. 40. 1. Ruleset invocations<br />“ruleset” == “mode”<br />In Carrot:<br /> ^myMode(myExpr)<br />In XSLT:<br /><xsl:apply-templates mode="myMode" select="myExpr"/><br />
  41. 41. 1. Ruleset invocations<br />“ruleset” == “mode”<br />In Carrot:<br /> ^myMode(myExpr)<br />In XSLT:<br /><xsl:apply-templates mode="myMode" select="myExpr"/><br />
  42. 42. 1. Ruleset invocations<br />“ruleset” == “mode”<br />In Carrot:<br /> ^myMode(myExpr)<br />In XSLT:<br /><xsl:apply-templates mode="myMode" select="myExpr"/><br />
  43. 43. 2. Shallow copy constructors<br />In Carrot: copy{…}<br />In XSLT:<xsl:copy>…</xsl:copy><br />
  44. 44. 2. Shallow copy constructors<br />In Carrot: copy{…}<br />In XSLT:<xsl:copy>…</xsl:copy><br />Why extend XQuery here?<br />The lack of shallow copy constructors in XQuery makes modified identity transforms impractical<br />(specifically, for preserving namespace nodes)<br />
  45. 45. 3. Text node literals<br />In Carrot:`my text node`<br />
  46. 46. 3. Text node literals<br />In Carrot:`my text node`<br />In XSLT (a literal text node):my text node<br />
  47. 47. 3. Text node literals<br />In Carrot:`my text node`<br />In XSLT (a literal text node):my text node<br />In XQuery (dynamic text node constructor):text{ "my text node" }<br />
  48. 48. 3. Text node literals<br />In Carrot:`my text node`<br />In XSLT (a literal text node):my text node<br />In XQuery (dynamic text node constructor):text{ "my text node" }<br />Why aren’t dynamic text constructors sufficient?<br />After all, they take only six more characters (text{…})<br />
  49. 49. 3. Text node literals<br />Consider an example:<br /><xsl:template match="/doc"> <result> <xsl:apply-templates mode="file-name" select="."/> <xsl:apply-templates mode="file-ext" select="."/> </result></xsl:template><xsl:template mode="file-name" match="doc">doc</xsl:template><xsl:template mode="file-ext" match="doc">.xml</xsl:template><br />
  50. 50. 3. Text node literals<br />Consider an example:<br /><xsl:template match="/doc"> <result> <xsl:apply-templates mode="file-name" select="."/> <xsl:apply-templates mode="file-ext" select="."/> </result></xsl:template><xsl:template mode="file-name" match="doc">doc</xsl:template><xsl:template mode="file-ext" match="doc">.xml</xsl:template><br />
  51. 51. 3. Text node literals<br />Consider an example:<br /><xsl:template match="/doc"> <result> <xsl:apply-templates mode="file-name" select="."/> <xsl:apply-templates mode="file-ext" select="."/> </result></xsl:template><xsl:template mode="file-name" match="doc">doc</xsl:template><xsl:template mode="file-ext" match="doc">.xml</xsl:template><br />
  52. 52. 3. Text node literals<br />Consider an example:<br /><xsl:template match="/doc"> <result> <xsl:apply-templates mode="file-name" select="."/> <xsl:apply-templates mode="file-ext" select="."/> </result></xsl:template><xsl:template mode="file-name" match="doc">doc</xsl:template><xsl:template mode="file-ext" match="doc">.xml</xsl:template><br />And the result:<br /><result>doc.xml</result><br />
  53. 53. 3. Text node literals<br />Same example, rewritten “naturally” in Carrot:<br />^(/doc) := <result>{^file-name(.), ^file-ext (.)}</result>; ^file-name(doc) := "doc";^file-ext(doc) := ".xml";<br />
  54. 54. 3. Text node literals<br />Same example, rewritten “naturally” in Carrot:<br />^(/doc) := <result>{^file-name(.), ^file-ext (.)}</result>; ^file-name(doc) := "doc";^file-ext(doc) := ".xml";<br />
  55. 55. 3. Text node literals<br />Same example, rewritten “naturally” in Carrot:<br />^(/doc) := <result>{^file-name(.), ^file-ext(.)}</result>; ^file-name(doc) := "doc";^file-ext(doc) := ".xml";<br />
  56. 56. 3. Text node literals<br />Same example, rewritten “naturally” in Carrot:<br />^(/doc) := <result>{^file-name(.), ^file-ext (.)}</result>; ^file-name(doc) := "doc";^file-ext(doc) := ".xml";<br />And the result (uh-oh):<br /> <result>doc .xml</result><br />
  57. 57. 3. Text node literals<br />Sequences of atomic values have spaces added upon conversion to a text node<br />Various fixes, none satisfactory:<br />Wrap the two invocations in text{} or concat()<br />(high coupling – what if one of them returns an element?)<br />Wrap the strings in text{}<br />(burdensome fix—regular strings work 90% of the time)<br />
  58. 58. 3. Text node literals<br />Note the imbalance:<br />Returning a text node is more concise in XSLT than in XQuery (!)<br />XSLT: Hello<br />XQuery: text{"Hello"}<br />Returning a string is more concise in XQuery than in XSLT<br />XQuery: "Hello"<br />XSLT: <xsl:sequence select="'Hello'"/><br />Text node literals in Carrot redress the imbalance<br />Text nodes in Carrot: `Hello`<br />Strings in Carrot: "Hello"<br />
  59. 59. 3. Text node literals<br />Rewritten properly in Carrot:<br />^(/doc) := <result>{^file-name(.), ^file-ext (.)}</result>; ^file-name(doc) := `doc`;^file-ext (doc) := `.xml`;<br />Simple guideline now:<br />Use text node literals when you are constructing part of a result document<br />Use string literals when you know you want to return a string<br />
  60. 60. Expression semantics<br />Same as XQuery!<br />With this exception (remember the earlier gripe):<br />Namespace attribute declarations on element constructors do not affect the default element namespace for XPath expressions.<br />Okay, enough about namespaces <br />
  61. 61. Carrot definitions<br />
  62. 62. A Carrot module<br />Consists of a set of unordered definitions<br />Three kinds of definitions:<br />Global variables<br />Functions<br />Rules<br />Unlike XQuery, there is no top-level expression—only definitions<br />Carrot is like XSLT in this regard<br />
  63. 63. Global variables<br />In Carrot:<br />$foo := "a string value";<br />
  64. 64. Global variables<br />In Carrot:<br />$foo := "a string value";<br />Equivalent to this XQuery:<br />declare variable $foo := "a string value";<br />
  65. 65. Global variables<br />In Carrot:<br />$foo := "a string value";<br />Equivalent to this XQuery:<br />declare variable $foo := "a string value";<br />
  66. 66. Functions<br />In Carrot:<br />my:foo() := "return value";<br />
  67. 67. Functions<br />In Carrot:<br />my:foo() := "return value";my:bar($str as xs:string) as xs:string := upper-case($str);<br />
  68. 68. Functions<br />In Carrot:<br />my:foo() := "return value";my:bar($str as xs:string) as xs:string := upper-case($str);<br />Equivalent to this XQuery:<br />declare function my:foo() { "return value" };declare function my:bar($str as xs:string) as xs:string { upper-case($str) };<br />
  69. 69. Functions<br />In Carrot:<br />my:foo() := "return value";my:bar($str as xs:string) as xs:string:= upper-case($str);<br />Equivalent to this XQuery:<br />declare function my:foo() { "return value" };declare function my:bar($str as xs:string) as xs:string{ upper-case($str) };<br />
  70. 70. Rule definitions<br />In Carrot:<br />^foo(*) := "return value";<br />Equivalent to this XSLT:<br /><xsl:template match="*" mode="foo"> <xsl:sequence select="'return value'"/></xsl:template><br />
  71. 71. Rule definitions<br />In Carrot:<br />^foo(*) := "return value";<br />Equivalent to this XSLT:<br /><xsl:template match="*" mode="foo"> <xsl:sequence select="'return value'"/></xsl:template><br />
  72. 72. Rule definitions<br />In Carrot:<br />^foo(*) := "return value";<br />Equivalent to this XSLT:<br /><xsl:template match="*" mode="foo"> <xsl:sequence select="'return value'"/></xsl:template><br />
  73. 73. Rule definitions<br />In Carrot:<br />^foo(*) := "return value";<br />Equivalent to this XSLT:<br /><xsl:template match="*" mode="foo"> <xsl:sequence select="'return value'"/></xsl:template><br />
  74. 74. Rule parameters<br />In Carrot:<br />^foo(* ; $str as xs:string) := concat($str, .);<br />
  75. 75. Rule parameters<br />In Carrot:<br />^foo(* ; $str as xs:string) := concat($str, .);<br />Equivalent to this XSLT:<br /><xsl:template match="*" mode="foo"> <xsl:param name="str" as="xs:string"/> <xsl:sequence select="concat($str, .)"/></xsl:template><br />
  76. 76. Rule parameters<br />In Carrot:<br />^foo(* ; $str as xs:string) := concat($str, .);<br />Equivalent to this XSLT:<br /><xsl:template match="*" mode="foo"><xsl:param name="str" as="xs:string"/> <xsl:sequence select="concat($str, .)"/></xsl:template><br />
  77. 77. Rule parameters<br />In Carrot:<br />^foo(* ; tunnel $str as xs:string) := concat($str, .);<br />Equivalent to this XSLT:<br /><xsl:template match="*" mode="foo"> <xsl:param name="str" as="xs:string" tunnel="yes"/> <xsl:sequence select="concat($str, .)"/></xsl:template><br />
  78. 78. Conflict resolution<br />Same as XSLT<br />Import precedence first<br />Then priority<br />
  79. 79. Explicit priorities<br />In Carrot:<br />^author-listing( author[1] ) 1 := ^();^author-listing( author ) := `, ` , ^();^author-listing( author[last()] ) := ` and ` , ^();<br />
  80. 80. Explicit priorities<br />In Carrot:<br />^author-listing( author[1] ) 1 := ^();^author-listing( author ) := `, ` , ^();^author-listing( author[last()] ) := ` and ` , ^();<br />Equivalent to this XSLT:<br /><xsl:template mode="author-listing" match="author[1]" priority="1"><br /> <xsl:apply-templates/><br /></xsl:template><br /><xsl:template mode="author-listing" match="author"><br /> <xsl:text>, </xsl:text><br /> <xsl:apply-templates/><br /></xsl:template><br /><xsl:template mode="author-listing" match="author[last()]"><br /> <xsl:text> and </xsl:text><br /> <xsl:apply-templates/><br /></xsl:template><br />
  81. 81. Explicit priorities<br />In Carrot:<br />^author-listing( author[1] ) 1:= ^();^author-listing( author ) := `, ` , ^();^author-listing( author[last()] ) := ` and ` , ^();<br />Equivalent to this XSLT:<br /><xsl:template mode="author-listing" match="author[1]" priority="1"><br /> <xsl:apply-templates/><br /></xsl:template><br /><xsl:template mode="author-listing" match="author"><br /> <xsl:text>, </xsl:text><br /> <xsl:apply-templates/><br /></xsl:template><br /><xsl:template mode="author-listing" match="author[last()]"><br /> <xsl:text> and </xsl:text><br /> <xsl:apply-templates/><br /></xsl:template><br />
  82. 82. Multiple modes<br />In Carrot:<br />^foo|bar(*) := `result`;<br />Equivalent to this XSLT:<br /><xsl:template mode="foo bar" match="*">result</xsl:template><br />
  83. 83. Multiple modes<br />In Carrot:<br />^foo|bar(*) := `result`;<br />Equivalent to this XSLT:<br /><xsl:template mode="foo bar" match="*">result</xsl:template><br />
  84. 84. Why I like composability<br />A couple of examples<br />
  85. 85. Pipelines are easier<br />A typical pipeline approach in XSLT:<br /><xsl:variable name="stage1-result"> <xsl:apply-templates mode="stage1" select="."/></xsl:variable><xsl:variable name="stage2-result"> <xsl:apply-templates mode="stage2" select="$stage1-result"/></xsl:variable><xsl:apply-templates mode="stage3" select="$stage2-result"/><br />
  86. 86. Pipelines are easier<br />A typical pipeline approach in XSLT:<br /><xsl:variable name="stage1-result"> <xsl:apply-templates mode="stage1" select="."/></xsl:variable><xsl:variable name="stage2-result"> <xsl:apply-templates mode="stage2" select="$stage1-result"/></xsl:variable><xsl:apply-templates mode="stage3" select="$stage2-result"/><br />In Carrot:<br />^stage1(.)/^stage2(.)/^stage3(.)<br />
  87. 87. Fewer features needed<br />XSLT 2.1/3.0 promises to add some convenience features, like:<br /><xsl:copy select="foo">…</xsl:copy><br />With Carrot, just use foo/copy{…}<br />
  88. 88. What about feature X?<br />
  89. 89. Two instruction categories<br />XSLT instructions that aren’t needed<br /><xsl:for-each> - Use for expressions (or mapping operator!)<br /><xsl:variable> - Use let instead<br /><xsl:sort> - Use order byinstead<br /><xsl:choose>, <xsl:if> - Use if…then…else instead<br />XSLT instructions whose Carrot syntax is TBD<br /><xsl:for-each-group><br /><xsl:result-document><br /><xsl:analyze-string><br />Etc., etc.<br />XQuery 3.0 may add grouping…<br />You can always import XSLT 2.0 stylesheets into Carrot<br />
  90. 90. Top-level elements<br />Imports and includes<br />import navigation.crt;include widgets.crt;<br />Top-level parameters<br />param $message as xs:string;<br />Etc.<br />Still in mock-up stage. See some examples:<br />http://github.com/evanlenz/carrot/examples<br />
  91. 91. Implementation strategy<br />
  92. 92. Compile to XSLT 2.0<br />1:1 module mapping<br />Each Carrot module compiles to an XSLT 2.0 module<br />Carrot can include and import other Carrot modules or XSLT modules.<br />Carrot can also import XQuery modules, but since this is not supported directly in XSLT 2.0, the semantics depend on your target XSLT processor, e.g.:<br /><saxon:import-query> in Saxon<br /><xdmp:import-module> in MarkLogic Server<br />
  93. 93. Steps to implementation<br />Generate a parser<br />Create a BNF grammar for Carrot<br />Hand-convert the EBNF grammar for XQuery expressions to BNF<br />Extend the resulting BNF to support Carrot definitions and expressions<br />Use yapp-xslt to generate the Carrot parser from the Carrot BNF<br />http://www.o-xml.org/yapp/<br />Already running into trouble with this approach…<br />Write a compiler (in XSLT, naturally)<br />
  94. 94. Project goals<br />At this point, just explore the raw ideas (and share them)<br />Solicit feedback<br />Placeholder for now: http://github.com/evanlenz/carrot<br />Help me cook this carrot <br />You write the parser, I’ll write the compiler?<br />
  95. 95. Future possibilities<br />
  96. 96. XML-oriented browser scripting<br />XQIB<br />Saxon-CE<br />Carrot, or something like it, could make XSLT more palatable to Web developers<br />
  97. 97. W3C activity <br />Provide seeds for ideas in the XSL/XQuery WGs?<br />Carrot will grow with XPath/XQuery/XSLT<br />
  98. 98. Mode merging<br />Random XSLT feature idea: invoke more than one mode<br /><xsl:apply-templates mode="foo bar"/><br />In Carrot:<br />^foo|bar()<br />A static mode extension mechanism<br />Handy for multi-stage transformations where each stage is similar to but not the same as the next<br />Could be added to Carrot even if not supported directly in XSLT<br />Carrot as a research playground for new language ideas<br />
  99. 99. Questions?<br />
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×