Sibelius Symphony no. 1
My orchestra is playing Sibelius 1 tomorrow in Columbia, Maryland. It’s not my favorite symphony, seems a little naive, though he wrote it when he was 35. If you wanna check it out, first check out the site.
My orchestra is playing Sibelius 1 tomorrow in Columbia, Maryland. It’s not my favorite symphony, seems a little naive, though he wrote it when he was 35. If you wanna check it out, first check out the site.
I love reading programming books, especially to learn a new programming language. Learning XSLT, I read a large number of books, as there are quite a few available. The quality of the XSLT books struck me as particularly all over the place, some were quite good while others weren’t even worth the time to skim. So I’m throwing together a simple list of my current collection of XSLT references, which happened to be my favorites of the bunch. These books are all geared towards specific audiences… beginners, advanced, etc, so I included their audiences.
(For disclosure, I did make the links amazon referrals. I feel kinda weird, but figured why not. I don’t expect any results, but if I got some, it’d go straight to buying a new book.)
Continue readingRecursion is one of the core concepts in programming. It’s valuable not only as a technique for writing programs, but as a general concept for solving problems. XSLT provides many useful elements such as for-each (and apply-templates), but occasionally you will run into a problem which must be solved with recursion. Let’s take a look at a real-world (no Fibonacci!!) example, where we have to operate on a simple string of numbers separated by commas. We’ll take a step-by-step approach to writing a recursive template.
Let’s say we have the following source document, short and sweet. We want to take each number, and wrap it with an element.
<?xml version="1.0" encoding="UTF-8"?>
<comma>1,2,3,4,5,6,7,88,99,100</comma>
The easy way to do this is to use the EXSLT str:tokenize function, which takes a string and some delimiters and splits the string based on those delimiters. All we do is add the xmlns:str and extension-element-prefixes attributes to our xsl:stylesheet declaration, and then call the str:tokenize function.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" xmlns:str="http://exslt.org/strings"
extension-element-prefixes="str">
<xsl:template match="/>
<xsl:for-each select="str:tokenize( comma, ',')">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
The result is, (new-lines added for readability):
<?xml version="1.0"?>
<token>1</token>
<token>2</token>
<token>3</token>
<token>4</token>
<token>5</token>
<token>6</token>
<token>7</token>
<token>88</token>
<token>99</token>
<token>100</token>
Excellent. But let’s say that we don’t have access to the EXSLT functions, and we have to write a template to perform the same thing.
So now we think up a recursive algorithm. Let’s look at a simplified list with three numbers, such as “1,2,3”. First, we print the “1”, the value before the first comma, and then we discard the first comma. At that point, our list will be “2,3” and we repeat, printing the new first value, and discarding the new first comma. Finally, the list becomes only “3”. There is no comma, so we simply print out the rest of the list, “3”. So we will be recursing over the string printing the first number, and then popping off the first number and first comma. This technique will work with a three number list, or a million-number list (though your processor will probably run out of memory before that).
XPath’s “substring-before”, “substring-after”, and “contains” functions are all of the tools that we’ll need to implement our algorithm. “substring-before” lets us obtain the number before the first comma. “substring-after” lets us discard the first number and first comma, and “contains” allows us figure out the last, comma-less case.
Our function starts in the same manner as all recursive functions, dealing with the last case, and then all of the cases before it. The last case will be the comma-less case from our algorithm. So here’s our template skeleton.
Continue readingUsing XSLT to copy elements is extremely common when you’re transforming a source document of a certain type (XML, HTML, etc.) to the same type. Often, you need an exact copy of an element verbatim, but other times you need to selectively choose certain elements to copy and others to discard. XSLT makes this process quite elegant using it’s xsl:copy-of and xsl:copy elements. The following is a setp-by-step tutorial on how these elements are used.
When you need an exact copy of an element and it’s children, you use the xsl:copy-of element, which makes an exact copy of the selected element and it’s children. Given the following XML data, which represents a (trivial) inventory of a store, let’s say you want an exact copy of any items with the name “XSLT”.
<pre lang="xml">
<?xml version="1.0" encoding="UTF-8"??><inventory><item id="1"><name>The Little Schemer</name><type>book</type><author>Friedman</author><author>Felleisen</author><list-price>29.95</list-price><sell-price>26.99</sell-price><cost>17.92</cost></item><item id="2"><name>XSLT</name><type>book</type><author>Tidwell</author><list-price>49.95</list-price><sell-price>34.99</sell-price><cost>22.92</cost></item><item id="3"><name>Romeo and Juliet</name><type>compact disc</type><conductor>Rostropovich</conductor><list-price>18.98</list-price><sell-price>13.99</sell-price><cost>9.92</cost></item></inventory>
You simply apply the following XSLT stylesheet to your source document:
<pre lang="xml">
<?xml version="1.0" encoding="UTF-8"??><stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><template match="/"><copy-of select="inventory/item[name = 'XSLT']"></copy-of></template></stylesheet>
Which gives you exactly what you were looking for, the “item” with the name “XSLT”.
<pre lang="xml">
<?xml version="1.0" encoding="utf-8"??><item id="2"><name>XSLT</name><type>book</type><author>Tidwell</author><list-price>49.95</list-price><sell-price>34.99</sell-price><cost>22.92</cost></item>
That was easy, so now let’s say you want to do a little more with your inventory document. Your boss wants a copy of it to look at the numbers and do some accounting. She doesn’t care about the authors or conductors, so she’d like that information left out. Also, she would like an additional piece of information for each item, the amount of profit off each item sold, the difference between the sell-price and the cost.
Because we are adding a piece of information and getting rid of elements that don’t affect the accounting, we can’t use a xsl:copy-of, because that would output an exact copy of the item element, it’s attribute nodes, and it’s child nodes. This exact copy is called a deep copy, because it not only copies the element, but all of it’s children as well. The solution is to use xsl:copy which performs a shallow copy, which means it only copies the current node, and ignores all children or attribute nodes.
Since xsl:copy only copies one element at a time, you need to explicitly specify that you want to continue copying attribute nodes and child nodes. xsl:apply-templates gives us the leverage to write a template that accomplishes that. The following template starts by matching attribute and children nodes, then copies the node, and recursively applies itself to any attribute or child nodes found in the source tree.
Continue readingI don’t typically link to other blogs/articles, nor do I mention classical music particularly often, but I found this article and blog entry so interesting and thought-provoking that they deserve a re-post.
First, a moving blog entry from David Finlayson, trombonist in the New York Philharmonic, and second, the New York Times article describing the background, as well as referencing the blog post.
While I’ve never had a specifically parallel experience, I can relate to the concepts of “fakes” in a particular industry. I find Mr. Finlayson’s reaction (that all musicians must take responsibility and blame for the situation) to be both bold, yet… well, correct. It takes a strong person to identify a stormy situation clearly and react in an appropriate fashion. I only hope that I would react the same way given the circumstanses.