Fork of yml2 for pypi maintenance
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1069 lines
33 KiB

5 years ago
  1. include homepage.en.yhtml2
  2. page "YSLT – XSLT C style" {
  3. h1 id=intro > YSLT – an introduction
  4. p >>
  5. Especially the ¬http://www.w3.org/TR/xslt XSLT¬ programmer can benefit from YML.
  6. Usually many attributes of XSLT are annoying in programming praxis:
  7. >>
  8. ul {
  9. li >>
  10. the missing separation of ¬http://en.wikipedia.org/wiki/Indent_style indention¬
  11. of the XSLT program and indention of the output text
  12. >>
  13. li > the complicated syntax
  14. li > the lack of good text escaping mechanisms (< and > are not seldom)
  15. li > ...
  16. }
  17. p > In short, it's ugly ;-)
  18. p >>
  19. Usually the result is, that many programmers are avoiding XSLT as a programming language.
  20. It's a pity, because for processing XML data, it can do much more than “formatting” as
  21. “stylesheets”.
  22. >>
  23. p >>
  24. The idea of YSLT now is to supply a simple language, which programmers want to use, to
  25. make the features of XSLT accessible to a broader base of people.
  26. >>
  27. p >>
  28. YSLT can be used much simpler; it's just a ¬http://fdik.org/yml/index#ylanguages Y Language¬
  29. for XSLT. I'm using it for my blog, here you can ¬http://fdik.org/yblog2.tar.bz2 download YBlog2¬,
  30. a simple blogging software in YSLT.
  31. >>
  32. p > Here you can find the ¬yslt.yml2 YSLT specification¬.
  33. h2 id=hello > Hello, World
  34. p > In YSLT, the hello world program reads like this:
  35. Code ||
  36. include yslt.yml2
  37. textstylesheet template "/" | hello, world
  38. ||
  39. p >>
  40. The `a href="http://fdik.org/yml/features#including" code > include` line includes the
  41. YSLT Y Language declarations. The second line generates an XSLT hello world program.
  42. You can generate it using:
  43. >>
  44. Code | % yml2c -o hello.xsl hello.ysl2
  45. p > This results in the following program:
  46. Code ||
  47. <xsl:stylesheet xmlns:func="http://exslt.org/functions"
  48. xmlns:dyn="http://exslt.org/dynamic" xmlns:str="http://exslt.org/strings"
  49. xmlns:math="http://exslt.org/math"
  50. xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  51. extension-element-prefixes="exsl func str dyn set math"
  52. xmlns:set="http://exslt.org/sets" version="1.0"
  53. xmlns:exsl="http://exslt.org/common"><xsl:output method="text"/>
  54. <xsl:variable name="space" select="' '"/>
  55. <xsl:param name="autoindent" select="4"/><xsl:template match="/">
  56. <xsl:param name="_indent" select="0"/><xsl:value-of
  57. select="substring($space, 1, $_indent+0*$autoindent)"/>hello, world
  58. </xsl:template></xsl:stylesheet>
  59. ||
  60. p >>
  61. You can execute this program with any
  62. ¬http://en.wikipedia.org/wiki/XML_template_engine XSL processor¬, for example the Free Software
  63. ¬http://xmlsoft.org/XSLT/xsltproc2.html xsltproc¬.
  64. >>
  65. Code ||
  66. % yml2c -o hello.xsl hello.ysl2
  67. % echo '<empty/>' > empty.xml
  68. % xsltproc hello.xsl empty.xml
  69. hello, world
  70. % _
  71. ||
  72. p >>
  73. Or you can just use ¬toolchain#processor yml2proc¬:
  74. >>
  75. Code ||
  76. % yml2proc -My hello.ysl2
  77. hello, world
  78. % _
  79. ||
  80. h2 id=programming > Programming in YSLT
  81. p >>
  82. Because YSLT is just a ¬index#ylanguages Y Language¬ for XSLT, you can do anything with YSLT
  83. you can do with XSLT in just nicer syntax ;-) To read what XSLT is all about, I recommend
  84. ¬http://www.w3.org/TR/xslt the official W3C documentation for XSLT¬.
  85. >>
  86. p >>
  87. So this document is just an beginners guide, if you want to understand XSLT completely,
  88. better read the ¬http://www.w3.org W3C¬ stuff.
  89. >>
  90. h3 > Programming YSLT means programming with a pure functional language.
  91. p >>
  92. Lovers of ¬http://en.wikipedia.org/wiki/Lisp_(programming_language) Lisp¬ or
  93. ¬http://www.haskell.org/ Haskell¬ will not see any problems. But many programmers are used to
  94. have a programming language with a
  95. ¬http://en.wikipedia.org/wiki/Procedural_programming procedural imperative paradigma¬ like
  96. ¬http://java.sun.com Java¬,
  97. ¬http://en.wikipedia.org/wiki/C_(programming_language) C¬/¬http://en.wikipedia.org/wiki/C++ C++¬
  98. or ¬http://www.python.org Python¬. Why should they use a
  99. ¬http://en.wikipedia.org/wiki/Functional_programming functional¬ language?
  100. >>
  101. p >>
  102. Actually, if a functional language is practical or not, depends of what's to do – “the
  103. right tool for the task”, one could say.
  104. >>
  105. p >>
  106. Because processing XML data means traversing a (document) tree,
  107. ¬http://en.wikipedia.org/wiki/Recursion recursive¬ algorithms are a clear advantage.
  108. And this is the reason, why choosing a functional language is a good choice for that job.
  109. >>
  110. p >>
  111. It's a little bit like with ¬http://en.wikipedia.org/wiki/SQL SQL¬ – for it's job, it's
  112. excellent, but no-one wants to write a complete application in SQL (and also not in one
  113. of the Turing-complete SQL extension languages like
  114. ¬http://www.oracle.com/technology/tech/pl_sql/index.html PL/SQL¬).
  115. >>
  116. h3 id=htmlgen > Generating HTML out of a DSL
  117. p >>
  118. Of course, you can use YSLT as you would use XSLT. Let's say, you have data in XML
  119. documents, and you want to have an excerpt out of this data. This is a common task,
  120. comparable to «SELECT» data out of an SQL database. But we have no database, we have
  121. something like this file customers.yml2:
  122. >>
  123. Code ||
  124. decl customer(*id, *name) { id *id, name *name };
  125. list {
  126. customer 23, "Kurt Meier";
  127. customer 42, "Lieschen Schmidt";
  128. }
  129. ||
  130. p >>
  131. Let's say, we want to output this into an ¬http://en.wikipedia.org/wiki/XHTML XHTML¬ document,
  132. where the list is showed as a table. Then we would do the following:
  133. >>
  134. p > The XHTML document should be like the following and include the list in the body:
  135. Code ||
  136. include yslt.yml2
  137. stylesheet {
  138. template "/" html {
  139. head title "Customer List";
  140. body apply "list";
  141. }
  142. ||
  143. p >>
  144. In the example above, stylesheet declares the main program. Then we define a template, which
  145. is executed automatically starting reading the root «'/'» of the document tree of the XML
  146. document we're processing.
  147. >>
  148. p > Using the XML document as input, we're creating this HTML tree:
  149. Code ||
  150. <html>
  151. <head>
  152. <title>Customer List</title>
  153. </head>
  154. <body>
  155. <!-- ... ->
  156. </body>
  157. </html>
  158. ||
  159. p > How do we create the list? Well, let's use a table with customers:
  160. Code | template "list" table apply "customer";
  161. p >>
  162. What to do per customer? Well, generate a table row with two columns, one for «id» and one
  163. for «name»:
  164. >>
  165. Code ||
  166. template "customer" tr {
  167. td value "id";
  168. td value "name";
  169. }
  170. }
  171. ||
  172. p > That was it. We now can run our small program:
  173. Code | % yml2proc -y customer.ysl2 -x customer.xml -o customer.html -P
  174. p > The result looks like this:
  175. Code ||
  176. % cat customer.html
  177. <?xml version="1.0"?>
  178. <html>
  179. <head>
  180. <title>Customer List</title>
  181. </head>
  182. <body>
  183. <table>
  184. <tr>
  185. <td>23</td>
  186. <td>Kurt Meier</td>
  187. </tr>
  188. <tr>
  189. <td>42</td>
  190. <td>Lieschen Schmidt</td>
  191. </tr>
  192. </table>
  193. </body>
  194. </html>
  195. % _
  196. ||
  197. p > Here you can download ¬samples/customer.ysl2 the complete program¬.
  198. h3 id=codegen > How to generate code with YSLT
  199. p > Generating code is easy with YSLT, if you follow these steps:
  200. ol {
  201. li > design the software you want to generate using patterns and write that in a DSL
  202. li > write target code once for each pattern
  203. li > deconstruct a compiler for the target code for each pattern
  204. li > fine tune until the diff is empty
  205. }
  206. p >>
  207. Let's test by example. First let's say, we have a pattern of entities we want
  208. to implement as Java beans. The enities in our DSL are:
  209. >>
  210. Code ||
  211. decl entity +name;
  212. decl attr +type +name;
  213. decl aggregates +entity;
  214. structure {
  215. entity Customer {
  216. attr String name;
  217. attr int creditLimit;
  218. aggregates Order;
  219. }
  220. entity Order {
  221. attr String no;
  222. attr String description;
  223. attr int amount;
  224. }
  225. }
  226. ||
  227. p >>
  228. How to write that in a Java Program? Well, following the second step, we're
  229. writing our target code manually; for this simple sample, let's be naive and
  230. save the following into a file named Customer.java.target:
  231. >>
  232. Code ||
  233. import java.util.Vector;
  234. import java.util.Collections;
  235. import base.Entity;
  236. class Customer extends Entity {
  237. Customer {
  238. id = genId();
  239. }
  240. // attribute name
  241. private String name;
  242. public String getName() {
  243. return name;
  244. }
  245. public void setName(String value) {
  246. name = value;
  247. }
  248. // attribute creditLimit
  249. private int creditLimit;
  250. public int getCreditLimit() {
  251. return creditLimit;
  252. }
  253. public void setCreditLimit(int value) {
  254. creditLimit = value;
  255. }
  256. // Order aggregation
  257. protected Vector orderList = new Vector();
  258. void addOrder(Order entity) {
  259. orderList.add(entity);
  260. }
  261. void removeOrder(Order entity) {
  262. orderList.remove(entity);
  263. }
  264. Iterator orderIterator() {
  265. return orderList.iterator();
  266. }
  267. }
  268. ||
  269. p >>
  270. The third step does most of the work. First we cite this code
  271. into gen_entity.ysl2 and create the basic form of an YSLT script:
  272. >>
  273. Code ||
  274. include yslt.yml2
  275. tstylesheet {
  276. template "/" {
  277. | import java.util.Vector;
  278. | import java.util.Collections;
  279. | import base.Entity;
  280. |
  281. | class Customer extends Entity {
  282. | Customer {
  283. | id = genId();
  284. | }
  285. |
  286. | // attribute name
  287. |
  288. | private String name;
  289. | public String getName() {
  290. | return name;
  291. | }
  292. | public void setName(String value) {
  293. | name = value;
  294. | }
  295. |
  296. | // attribute creditLimit
  297. |
  298. | private int creditLimit;
  299. | public int getCreditLimit() {
  300. | return creditLimit;
  301. | }
  302. | public void setCreditLimit(int value) {
  303. | creditLimit = value;
  304. | }
  305. |
  306. | // Order aggregation
  307. |
  308. | protected Vector orderList = new Vector();
  309. | void addOrder(Order entity) {
  310. | orderList.add(entity);
  311. | }
  312. | void removeOrder(Order entity) {
  313. | orderList.remove(entity);
  314. | }
  315. | Iterator orderIterator() {
  316. | return orderList.iterator();
  317. | }
  318. | }
  319. }
  320. }
  321. ||
  322. p >>
  323. Now for the deconstruction. I think, it'll be best, if we
  324. ¬#edocument create a .java file for each entity¬.
  325. So we're moving the whole thing into a template for each entity
  326. creating a file, and we're applying this for each entity using the name of each
  327. Entity as parameter. We're adding some distinction of cases, too.
  328. >>
  329. p >>
  330. When we apply, the indention system of YSLT will add an indention level, so we can
  331. take out rendundant whitespace; for the first apply we don't want this, so we're
  332. giving the number 0 as the indention level.
  333. >>
  334. p >>
  335. In attributes, braces «{…}» let us insert the value of an XPath expression into our
  336. DSL, while inside quoted text the same is done by the ¬#angledouble angle double quotes¬
  337. `] <code>&#xab…&#xbb</code>`:
  338. >>
  339. Code ||
  340. include yslt.yml2
  341. tstylesheet {
  342. template "/structure" apply "Entity", 0;
  343. template "Entity" document "{@name}.java" {
  344. if "aggregates" {
  345. | import java.util.Vector;
  346. | import java.util.Collections;
  347. }
  348. | import base.Entity;
  349. |
  350. | class `] &#xab`@name`] &#xbb` extends Entity {
  351. | `] &#xab`@name`] &#xbb` {
  352. | id = genId();
  353. | }
  354. |
  355. [...]
  356. | orderList.remove(entity);
  357. | }
  358. | Iterator orderIterator() {
  359. | return orderList.iterator();
  360. | }
  361. | }
  362. }
  363. }
  364. ||
  365. p >>
  366. Well, not bad. Now for the pattern of an attribute and an aggregation, respectively.
  367. >>
  368. Code ||
  369. include yslt.yml2
  370. tstylesheet {
  371. template "/structure" apply "Entity";
  372. template "Entity" document "{@name}.java" {
  373. if "aggregates" {
  374. | import java.util.Vector;
  375. | import java.util.Collections;
  376. }
  377. | import base.Entity;
  378. |
  379. | class `] &#xab`@name`] &#xbb` extends Entity {
  380. | `] &#xab`@name`] &#xbb` {
  381. | id = genId();
  382. | }
  383. |
  384. apply "attr|aggregates";
  385. | }
  386. }
  387. template "attr" {
  388. |
  389. | // attribute `] &#xab`@name`] &#xbb`
  390. |
  391. | private `] &#xab`@type`] &#xbb` `] &#xab`@name`] &#xbb`;
  392. | public `] &#xab`@type`] &#xbb` get`] &#xab`@name`] &#xbb`() {
  393. | return `] &#xab`@name`] &#xbb`;
  394. | }
  395. | public void set`] &#xab`@name`] &#xbb`(`] &#xab`@type`] &#xbb` value) {
  396. | `] &#xab`@name`] &#xbb` = value;
  397. | }
  398. }
  399. template "aggregates" {
  400. |
  401. | // `] &#xab`@entity`] &#xbb` aggregation
  402. |
  403. | protected Vector `] &#xab`@entity`] &#xbb`List = new Vector();
  404. | void add`] &#xab`@entity`] &#xbb`(`] &#xab`@entity`] &#xbb` entity) {
  405. | `] &#xab`@entity`] &#xbb`List.add(entity);
  406. | }
  407. | void remove`] &#xab`@entity`] &#xbb`(`] &#xab`@entity`] &#xbb` entity) {
  408. | `] &#xab`@entity`] &#xbb`List.remove(entity);
  409. | }
  410. | Iterator `] &#xab`@entity`] &#xbb`Iterator() {
  411. | return `] &#xab`@entity`] &#xbb`List.iterator();
  412. | }
  413. }
  414. }
  415. ||
  416. p >>
  417. As you can see, we're deconstructing step by step. This is a good idea to get
  418. into code generation with YSLT, but it remains a good idea even for the advanced
  419. programmer: it keeps a clear view on what's happening.
  420. >>
  421. p >>
  422. In the last step, test it out and make a diff to your target code. You will see
  423. that our example needs some beautifying: in Java, camel case is important and
  424. makes you some work to revert characters to uppercase or lowercase, respectively.
  425. For that work you'll see that ¬http://www.w3.org/TR/xpath/#function-translate XPath's translate() function¬ is a little bit ugly ;-)
  426. So we're defining an ¬features#userop operator¬ for that at the top of the file:
  427. >>
  428. Code ||
  429. define operator "“(.*?)”" as call "ucase" with "text", "%1";
  430. ||
  431. p >>
  432. Inside the template, we're defining the ucase function:
  433. >>
  434. Code ||
  435. function "ucase" {
  436. param "text";
  437. value "translate(substring($text,1,1),'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')";
  438. value "substring($text, 2)";
  439. }
  440. }
  441. ||
  442. p >>
  443. Now we can replace one quoting with another; have a look at the getter and setter
  444. methods:
  445. >>
  446. Code ||
  447. include yslt.yml2
  448. define operator "“(.*?)”" as call "ucase" with "text", "%1";
  449. tstylesheet {
  450. template "/structure" apply "Entity";
  451. [...]
  452. template "attr" {
  453. |
  454. | // attribute `] &#xab`@name`] &#xbb`
  455. |
  456. | private `] &#xab`@type`] &#xbb` `] &#xab`@name`] &#xbb`;
  457. | public `] &#xab`@type`] &#xbb` get“@name”() {
  458. | return `] &#xab`@name`] &#xbb`;
  459. | }
  460. | public void set“@name”(`] &#xab`@type`] &#xbb` value) {
  461. | `] &#xab`@name`] &#xbb` = value;
  462. | }
  463. }
  464. [...]
  465. function "ucase" {
  466. param "text";
  467. value "translate(substring($text,1,1),'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')";
  468. value "substring($text, 2)";
  469. }
  470. }
  471. ||
  472. p >>
  473. Well, the rest is a pure laborious task ;-) Feel free to complete. And: use diff!
  474. >>
  475. h3 id=ddlgen > A more advanced example: generating SQL DDL out of an UML diagram
  476. p >>
  477. Well, now for something real ;-) This is a very common task: somebody models
  478. with an ¬http://en.wikipedia.org/wiki/Class_diagram UML class diagram¬, and you want
  479. to have SQL ¬http://en.wikipedia.org/wiki/Data_Definition_Language DDL¬, which generates
  480. a matching database structure.
  481. >>
  482. p > Let's go:
  483. p >>
  484. First, lets use a stylesheet, which declares the needed
  485. ¬http://www.w3.org/TR/REC-xml-names/ XMI namespaces¬:
  486. >>
  487. Code ||
  488. include yslt.yml2
  489. tstylesheet xmlns:uml="http://schema.omg.org/spec/UML/2.1",
  490. xmlns:xmi="http://schema.omg.org/spec/XMI/2.1" {
  491. ||
  492. p > Now, search the Model for all content:
  493. Code | template "/" apply "xmi:XMI/uml:Model/packagedElement", 0;
  494. p >>
  495. We're translating ¬http://en.wikipedia.org/wiki/Package_(UML) UML Packages¬ into
  496. underscore separated prefixes:
  497. >>
  498. Code ||
  499. template "packagedElement[@xmi:type='uml:Package']" {
  500. param "name", "''";
  501. if "$name=''" apply "packagedElement", 0 { with "name", "@name"; }
  502. if "$name!=''" apply "packagedElement", 0 { with "name", "concat($name, '_', @name)"; }
  503. }
  504. ||
  505. p > Each Class is represented by a table in the database:
  506. Code ||
  507. template "packagedElement[@xmi:type='uml:Class']" {
  508. param "name";
  509. | CREATE TABLE «$name»_«@name» (
  510. apply "ownedAttribute";
  511. | );
  512. }
  513. ||
  514. p >>
  515. Finally, for each different data type for an attribute we're outputting different fields
  516. with different types:
  517. >>
  518. Code ||
  519. template "ownedAttribute[@xmi:type='uml:Property' and type/@xmi:type='uml:PrimitiveType']" {
  520. 0> «@name»
  521. choose {
  522. when "type/@href='http://schema.omg.org/spec/UML/2.1/uml.xml#String'"
  523. > VARCHAR
  524. // [...] for other types, extend when clauses
  525. }
  526. if "position()!=last()" > ,
  527. text "\\n";
  528. }
  529. }
  530. ||
  531. p > Our little sample only supports «VARCHAR», but it is an easy game to play to complete that.
  532. p >>
  533. Here you can download the ¬samples/xmi2ddl.ysl2 XMI 2 DDL compiler sample¬. I used
  534. ¬http://bouml.free.fr/ BOUML¬ to create a small ¬samples/demo.xmi UML sample file¬
  535. as ¬http://www.omg.org/spec/XMI/ XMI 2.1¬.
  536. >>
  537. p > To compile that, use:
  538. Code ||
  539. % yml2proc -y xmi2ddl.ysl2 -x demo.xmi
  540. CREATE TABLE demo_Customer (
  541. id VARCHAR,
  542. name VARCHAR
  543. );
  544. % _
  545. ||
  546. p >>
  547. In the samples directory you'll find
  548. ¬samples/xmi2ddl.uml2 a prettier solution¬ using ¬samples/uml.yml2 some declares to prettify¬.
  549. >>
  550. h1 id=features > Features of YSLT
  551. p >>
  552. Because YSLT just generates XSLT programs, it will be a good idea to read the
  553. ¬http://www.w3.org/TR/xslt XSLT Documentation¬ as well as the
  554. ¬http://www.w3.org/TR/xpath XPath Documentation¬.
  555. >>
  556. p >>
  557. In the following, you find a ¬#functionlist List of YSLT Functions¬ and a
  558. ¬#operatorlist List of YSLT Operators¬.
  559. >>
  560. h2 id=functionlist > List of YSLT Functions
  561. h3 > apply(select, *indent=1)
  562. p >>
  563. Generates the «<xsl:apply-templates />»
  564. ¬http://www.w3.org/TR/xslt#section-Applying-Template-Rules tag¬. The «*indent» pointer gives
  565. the number of indention levels to add (default: 1) for the Indention System.
  566. >>
  567. p i > Example:
  568. Code | apply "attr|aggregation", mode=define;
  569. h3 id=assert > assert(test, msg)
  570. p >>
  571. Generates «<xsl:value-of select="yml:assert(test, msg)"». See the ¬#ymlassert yml:assert() XPath extension¬.
  572. This function does not generate anything when not being called by ¬toolchain#processor ysltproc¬
  573. with the --debug switch.
  574. >>
  575. h3 > attrib(name, namespace)
  576. p > Generates the «<xsl:attribute />» ¬http://www.w3.org/TR/xslt#creating-attributes tag¬.
  577. h3 > call(name)
  578. p >>
  579. Generates the «<call-template />» ¬http://www.w3.org/TR/xslt#named-templates tag¬.
  580. Used to call a «function()».
  581. >>
  582. p i > Example:
  583. Code | call "ucase" with "text", "$name";
  584. h3 > choose()
  585. p >>
  586. Generates the «<xsl:choose />»
  587. ¬http://www.w3.org/TR/xslt#section-Conditional-Processing-with-xsl:choose tag¬.
  588. Use in a «choose() ... when()... otherwise()...» structure.
  589. >>
  590. p i > Example:
  591. Code ||
  592. choose {
  593. when "$id=1"
  594. > yes
  595. when "$id=2"
  596. > no
  597. otherwise
  598. error "invalid id";
  599. }
  600. ||
  601. h3 > comment()
  602. p > Generates the «<xsl:comment />» ¬http://www.w3.org/TR/xslt#section-Creating-Comments tag¬.
  603. p i > Example:
  604. Code | comment "this comment will remain in XML";
  605. h3 > const(name, select)
  606. p > Generates the «<xsl:variable />» ¬http://www.w3.org/TR/xslt#variables tag¬.
  607. p i > Example:
  608. Code | const "pi", 3.14;
  609. h3 > copy(select)
  610. p > Generates the «<xsl:copy-of />» ¬http://www.w3.org/TR/xslt#copy-of tag¬.
  611. p i > Example:
  612. Code | copy ".";
  613. h3 id=debug > debug(msg)
  614. p >>
  615. Generates «<xsl:value-of select="yml:debug(msg)"». See the ¬#ymldebug yml:debug() XPath extension¬.
  616. This function does not generate anything when not being called by ¬toolchain#processor ysltproc¬
  617. with the --debug switch.
  618. >>
  619. h3 > def(name)
  620. p >>
  621. Generates the ¬http://www.exslt.org EXSLT¬ «<func:funcion />»
  622. ¬http://www.exslt.org/func/elements/function/ tag¬.
  623. >>
  624. h3 id=edocument > document(href, method)
  625. p >>
  626. Generates the ¬http://www.exslt.org EXSLT¬ «<exsl:document />»
  627. ¬http://www.exslt.org/exsl/elements/document/ tag¬.
  628. >>
  629. p i > Example:
  630. Code ||
  631. template "entity" document "{@name}.java" {
  632. […]
  633. }
  634. ||
  635. h3 > element(name, namespace)
  636. p >>
  637. Generates the «<xsl:element />»
  638. ¬http://www.w3.org/TR/xslt#section-Creating-Elements-with-xsl:element tag¬.
  639. >>
  640. h3 > error()
  641. p >>
  642. Generates the «<xsl:message />» ¬http://www.w3.org/TR/xslt#message tag¬
  643. with attribute «terminate» set to "yes".
  644. >>
  645. h3 > estylesheet(*output="xml")
  646. p >>
  647. Does the same as «stylesheet()», but additionally declares the ¬http://www.exslt.org/ EXSLT¬
  648. functions of the groups «exsl», «func», «str», «dyn», «set» and «math» and declares the
  649. corresponding name spaces.
  650. >>
  651. h3 > for(select)
  652. p > Generates the «<xsl:for-each />» ¬http://www.w3.org/TR/xslt#for-each tag¬.
  653. p i > Example:
  654. Code | for "../structure[@name='hello'" > «@type»
  655. h3 > foreach(select)
  656. p > Same as «for()».
  657. h3 > function(name)
  658. p >>
  659. Generates the «<xsl:template />» ¬http://www.w3.org/TR/xslt#named-templates tag¬.
  660. Used by calling with «call()».
  661. >>
  662. p i > Example:
  663. Code ||
  664. function "ucase" {
  665. param "text";
  666. value "translate(substring($text,1,1),'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')";
  667. value "substring($text, 2)";
  668. }
  669. ||
  670. h3 > if(test)
  671. p >>
  672. Generates the «<xsl:if />»
  673. ¬http://www.w3.org/TR/xslt#section-Conditional-Processing-with-xsl:if tag¬.
  674. >>
  675. p i > Example:
  676. Code | if "position()<last()" > ,
  677. h3 > import(href)
  678. p > Generates the «<xsl:import />» ¬http://www.w3.org/TR/xslt#import tag¬.
  679. h3 > key(name, match, use)
  680. p > Generates the «<xsl:key />» ¬http://www.w3.org/TR/xslt#key tag¬.
  681. h3 > message()
  682. p > Generates the «<xsl:message />» ¬http://www.w3.org/TR/xslt#message tag¬.
  683. h3 > otherwise()
  684. p >>
  685. Generates the «<xsl:otherwise />»
  686. ¬http://www.w3.org/TR/xslt#section-Conditional-Processing-with-xsl:choose tag¬.
  687. Use in a «choose() ... when()... otherwise()...» structure.
  688. >>
  689. h3 > output(method)
  690. p > Generates the «<xsl:output />» ¬http://www.w3.org/TR/xslt#output tag¬.
  691. h3 > param(name, select)
  692. p > Generates the «<xsl:param />» ¬http://www.w3.org/TR/xslt#variables tag¬.
  693. p i > Example:
  694. Code | param "x", 42;
  695. h3 > processing(name)
  696. p >>
  697. Generates the «<xsl:processing-instruction />»
  698. ¬http://www.w3.org/TR/xslt#section-Creating-Processing-Instructions tag¬.
  699. >>
  700. h3 > raw()
  701. p >>
  702. Generates the «<xsl:text />» ¬http://www.w3.org/TR/xslt#section-Creating-Text tag¬.
  703. Sets the attribute «disable-output-escaping» to "yes".
  704. >>
  705. h3 > result(select)
  706. p >>
  707. Generates the ¬http://www.exslt.org EXSLT¬ «<func:result />»
  708. ¬http://www.exslt.org/func/elements/result/ tag¬.
  709. >>
  710. h3 > stylesheet(*output="xml")
  711. p >>
  712. Generates the XSLT «<stylesheet />» ¬http://www.w3.org/TR/xslt#stylesheet-element tag¬.
  713. Additionally generates an «<output />» ¬http://www.w3.org/TR/xslt#output tag¬
  714. in the body, with attribute «method» set to the value of the pointer «*output» (default: "xml").
  715. >>
  716. p > The content you're giving is placed in the body after the «<output />» tag.
  717. p > The «version» attribute is set to "1.0" and XML namespace «xsl» is correctly defined.
  718. p >>
  719. In short: use for a stylesheet, just give the output type as parameter, if you don't want to
  720. to generate XML but HTML ("html") oder plain text ("text").
  721. >>
  722. p > «stylesheet()» additionally generates tags for the Indention System.
  723. h3 > template(match)
  724. p >>
  725. Generates the «<xsl:template />» ¬http://www.w3.org/TR/xslt#section-Defining-Template-Rules tag¬.
  726. Additionally generates tags for the Indention System.
  727. >>
  728. p i > Example:
  729. Code ||
  730. template "attr", mode=declare
  731. | attribute `] &#xab@type&#xbb` `] &#xab@name&#xbb`;
  732. ||
  733. h3 > text()
  734. p > Generate the «<xsl:text />» ¬http://www.w3.org/TR/xslt#section-Creating-Text tag¬.
  735. h3 > textstylesheet()
  736. p > Same as «estylesheet()», but «*output» is now "text", that means the stylesheet outputs plain text.
  737. h3 > tstylesheet()
  738. p > Same as «textstylesheet()».
  739. h3 > value(select)
  740. p > Generates the «<xsl:value-of />» ¬http://www.w3.org/TR/xslt#value-of tag¬.
  741. p i > Example:
  742. Code | value "@name";
  743. h3 > warning()
  744. p >>
  745. Generates the «<xsl:message />» ¬http://www.w3.org/TR/xslt#message tag¬
  746. with attribute «terminate» set to "no".
  747. >>
  748. h3 > when()
  749. p >>
  750. Generates the «<xsl:when />»
  751. ¬http://www.w3.org/TR/xslt#section-Conditional-Processing-with-xsl:choose tag¬.
  752. Use in a «choose() ... when()... otherwise()...» structure.
  753. >>
  754. h3 > with(name, select)
  755. p >>
  756. Generates the «<xsl:with-param />»
  757. ¬http://www.w3.org/TR/xslt#section-Passing-Parameters-to-Templates tag¬.
  758. >>
  759. p i > Example:
  760. Code | call "ucase" with "text", "$name";
  761. h2 id=operatorlist > List of YSLT Text Operators
  762. h3 id="angledouble" > Operator `] <code>&#xab…&#xbb</code>`
  763. p > Generate YSLT Function Call «value('…')».
  764. h2 id=xpathext > Debugging Functions
  765. p >>
  766. YML defines two functions in namespace http://fdik.org/yml, which are enabled if the command line
  767. option --debug is given in ¬yslt#processor yml2proc¬.
  768. >>
  769. h3 id=ymlassert > yml:assert(test, msg)
  770. p >>
  771. If XPath expression «test» evaluates to «false()» or to an empty set, XPath expression «msg» is
  772. printed to stderr; the compilation then aborts with an error.
  773. >>
  774. p >>
  775. Better don't use it directly, use the ¬#assert assert() YSLT function¬.
  776. >>
  777. h3 id=ymldebug > yml:debug(msg)
  778. p >>
  779. Prints XPath expression «msg» to stderr.
  780. >>
  781. p >>
  782. Better don't use it directly, use the ¬#debug debug() YSLT function¬.
  783. >>
  784. h2 id=stdlib > Standard Function Library
  785. p >>
  786. Additionally, you can «include standardlib.ysl2» in the body of your stylesheet.
  787. Then you'll have these extra functions:
  788. >>
  789. h3 id=dec2hex > yml:dec2hex(dec, digits=8)
  790. p >>
  791. Converts number «dec» into a string with a hexadecimal representation filled up to
  792. «digits» digits. If you're omitting the second parameter, it is set to 8.
  793. >>
  794. h3 id=hex2dec > yml:hex2dec(hex)
  795. p >>
  796. Converts the string «hex» consisting of hexadecimal digits into a number.
  797. >>
  798. h3 id=lcase > yml:lcase(text)
  799. p >>
  800. Converts all uppercase letters of string «text» into lowercase ones.
  801. >>
  802. h3 id=ucase > yml:ucase(text)
  803. p >>
  804. Converts all lowercase letters of string «text» into uppercase ones.
  805. >>
  806. div id=bottom {
  807. a href="features" "<< back to YML Features" " "
  808. a href="#top" "^Top^" " "
  809. a href="toolchain" "> > explain the Tool Chain" " "
  810. a href="yslt.en.yhtml2" "(source)"
  811. }
  812. }