<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jakob Külzer</title>
	<atom:link href="http://www.jakusys.de/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jakusys.de/blog</link>
	<description>Ninja Coding Monkey goes Canada</description>
	<lastBuildDate>Sun, 02 Jan 2011 20:12:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.3</generator>
		<item>
		<title>SSH (Remote) Tunnels</title>
		<link>http://www.jakusys.de/blog/2011/01/ssh-remote-tunnels/</link>
		<comments>http://www.jakusys.de/blog/2011/01/ssh-remote-tunnels/#comments</comments>
		<pubDate>Sun, 02 Jan 2011 20:12:18 +0000</pubDate>
		<dc:creator>Jakob Külzer</dc:creator>
				<category><![CDATA[Cool Tech]]></category>
		<category><![CDATA[remote tunnl]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[tunnel]]></category>

		<guid isPermaLink="false">http://www.jakusys.de/blog/?p=1287</guid>
		<description><![CDATA[Just figured out how SSH remote tunnels work and wanted to write it down. Nomenclature: [Local] Client: your local computer. In fact, if I say local, I mean the client. [Remote] Server: the server you connect to. If I say remote, I mean server. Forward Tunnels Your standard tunnel, allows you to take a local [...]]]></description>
			<content:encoded><![CDATA[<p>Just figured out how SSH remote tunnels work and wanted to write it down.</p>
<p>Nomenclature:</p>
<ul>
<li>[Local] Client: your local computer. In fact, if I say local, I mean the client.</li>
<li>[Remote] Server: the server you connect to. If I say remote, I mean server.</li>
</ul>
<h2>Forward Tunnels</h2>
<p>Your standard tunnel, allows you to take a local <span style="color: #339966;"><strong>port</strong></span> and redirect it to a <span style="color: #ff9900;"><strong>remote port</strong></span> on the server:</p>
<pre>$ ssh -L <span style="color: #ff9900;"><strong>REMOTEPORT</strong></span>:client:<span style="color: #339966;"><strong>CLIENTPORT</strong></span> user@server</pre>
<p>Now, that by opening a tunnel in this way:</p>
<pre>$ ssh -L <span style="color: #ff9900;"><strong>4040</strong></span>:localhost:<span style="color: #339966;"><strong>8080</strong></span> user@server</pre>
<p>you can connect to localhost:8080 and you'll get, through the tunnel, what's on server:4040.</p>
<h2>Remote Tunnels</h2>
<p>Regular forward tunnels are neat if you want to access a service that runs on a forbidden port through a firewall. But what if you need to map an incoming port on a remote server to a local port? Maybe because your ISP doesn't allow you NAT arbitrary ports?  Do not fear, remote tunnels are here for your rescue. They work pretty much the same way as regular tunnels, just the other way round. Instead of opening a listening socket on your local box, they open a port on the remote server. So, to  open a <span style="color: #ff9900;"><strong>port on your remote box</strong></span> and forward it to a <span style="color: #339966;"><strong>local port</strong></span>, use the following:</p>
<pre>$ ssh -R <span style="color: #ff9900;"><strong>REMOTEPORT</strong></span>:client:<span style="color: #339966;"><strong>CLIENTPORT</strong></span> user@server</pre>
<p>That's it. Well, almost. There's a catch. Per default sshd will now bind the listening socket to the loopback device. Kind of useless if you want to forward incoming connections through the tunnel. If you study the man page, you'll notice that you can specify a binding port for the remote tunnel:</p>
<pre>$ ssh -R <strong><span style="color: #800080;">BIND_ADDRESS</span></strong>:<strong><span style="color: #ff9900;">REMOTEPORT</span></strong>:client:<strong><span style="color: #339966;">CLIENTPORT</span></strong> user@server</pre>
<p>So, if your server's IP was 12.23.34.45, you would specify:</p>
<pre>$ ssh -R 12.23.34.45:8080:localhost:8080 user@server</pre>
<p>However, depending on your sshd configuration it might or might not work. Per default sshd won't let you just bind sockets to anything. You'll need to allow that, by specifying the GatewayPorts option in your sshd_config and restart sshd:</p>
<pre>GatewayPorts yes</pre>
<p>I got slightly confused, as the man page states that you can specify a value "clientspecified" to allow the client to select a specific interface, but it didn't work for me.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jakusys.de/blog/2011/01/ssh-remote-tunnels/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>My Case Against Code Comments</title>
		<link>http://www.jakusys.de/blog/2010/12/my-case-against-code-comments/</link>
		<comments>http://www.jakusys.de/blog/2010/12/my-case-against-code-comments/#comments</comments>
		<pubDate>Fri, 03 Dec 2010 05:39:05 +0000</pubDate>
		<dc:creator>Jakob Külzer</dc:creator>
				<category><![CDATA[Cool Tech]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Code Quality]]></category>
		<category><![CDATA[Comments]]></category>
		<category><![CDATA[Rant]]></category>

		<guid isPermaLink="false">http://www.jakusys.de/blog/?p=1268</guid>
		<description><![CDATA[If you were startled by the headline and wonder if it might be a typo, be assured, it is not. I am actually blogging against code comments. Yes, you heard that right. I am questioning, opposing the way that writing code is being taught, or at least, as it was taught when I was at [...]]]></description>
			<content:encoded><![CDATA[<p>If you were startled by the headline and wonder if it might be a typo, be assured, it is not. I am actually blogging <strong>against</strong> code comments. Yes, you heard that right. I am questioning, opposing the way that writing code is being taught, or at least, as it was taught when I was at university. "<em>Heretic!</em>" you might scream, "<em>Everything should be documented!</em>" or more calm voices might say "<em>Comments help developers understand code.</em>". And for the most part I really agree. Everything should be documented and help developers understand what they are reading. However, I don't agree with the method: comments are a very very bad way of explaining what a particular piece of code is supposed to do.<span id="more-1268"></span></p>
<p>I am currently working on a large legacy system that is full of old code and to a certain extend full of comments. But sadly, most of these comments are not helpful at all:</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008000; font-style: italic; font-weight: bold;">/**<br />
* Getter for foo.<br />
*/</span><br />
<span style="color: #000000; font-weight: bold;">public</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">String</span></a> getFoo<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> ... <span style="color: #009900;">&#125;</span></div></div>
<p>Wow. Useless. Why document a getter (or setter)? But that's ok, that's something I could live with. However, consider the following snippet:</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;">//get an instance of factory</span><br />
DocumentBuilderFactory dbf <span style="color: #339933;">=</span> DocumentBuilderFactory.<span style="color: #006633;">newInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span><br />
<span style="color: #666666; font-style: italic;">//get an instance of builder</span><br />
DocumentBuilder db <span style="color: #339933;">=</span> dbf.<span style="color: #006633;">newDocumentBuilder</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #666666; font-style: italic;">//create an instance of DOM</span><br />
dom <span style="color: #339933;">=</span> db.<span style="color: #006633;">newDocument</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
...</div></div>
<p>Ain't this helpful? Unfortunately not. However, a lot of developers seem to have the urge to document the obvious. That applies not only to real code statements, but to higher level entities as well:</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">foo.bar.blargh</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;">//==============================================================================</span><br />
<span style="color: #666666; font-style: italic;">//I M P O R T S</span><br />
<span style="color: #666666; font-style: italic;">//==============================================================================</span><br />
<br />
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">foo.bar.*</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">blargh.*</span><span style="color: #339933;">;</span><br />
<span style="color: #666666; font-style: italic;">//==============================================================================</span><br />
<span style="color: #666666; font-style: italic;">//C L A S S &nbsp; D E F I N I T I O N</span><br />
<span style="color: #666666; font-style: italic;">//==============================================================================</span><br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> FooBar <span style="color: #009900;">&#123;</span> ... <span style="color: #009900;">&#125;</span></div></div>
<p>As pretty as it looks, it's absolutely useless and a waste of screen estate. Everybody who is versed in Java (or your language of choice) will know that import statements are at the top of the class. Also, a range of lines that all start with the word "import" should give you a hint. Then there's the block indicating that a class definition will follow. Let this sink in. Is it that surprising and unconventional to find a class definition in a Java file that it has to be documented? I don't believe so. It is another example of wasted time and screen real estate.</p>
<p>Then there's another type of comments I run into a lot that make my life harder:</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;">/*<br />
for(int i = 0; i &amp;lt; getFoo().size(); i++) {<br />
String sl = (getBar().size() &amp;gt; 1 &amp;amp;&amp;amp; getBar().size() != (i + 1)) ? &quot; / &quot; : BLANK;<br />
blargh += getBar().get(i) + sl;<br />
}*/</span></div></div>
<p>Commented out code is another big mystery to me. The developer who commented out the code, forgot about it by now. And everybody else just doesn't know what to make of it. <em>Why is commented out</em>? <em>Why wasn't it removed completely</em>? All these questions pop up in a developers head. And because he doesn't have a good answer, he'll just leave that snippet sit there. In fact, I strongly believe that the best way to preserve code for eternity is to put it into a comment, as most developers won't touch it. Why so many developers keep doing that in the age of source code management tools is beyond me. Whenever I find a commented piece of code, I delete it. And so should you. If the code were important, it wouldn't be commented. And you know, it's not that those lines are contributing to the actual application. They are just landmines of confusion. Remove them.</p>
<p>And then we get to my personal nemesis, comments where the developers actually tried to explain something but only manage to confuse the reader even more:</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;">// if the keyword is &quot;*&quot; so it means anything or all the pages that will match the handles filter</span><br />
<span style="color: #666666; font-style: italic;">// so returning handles is enought (using default)</span><br />
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>OPTIONS_MAP.<span style="color: #006633;">containsKey</span><span style="color: #009900;">&#40;</span>optionsStr<span style="color: #009900;">&#41;</span><span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span><span style="color: #0000ff;">&quot;*&quot;</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>keyword<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> options <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Ainteger+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Integer</span></a><span style="color: #009900;">&#41;</span> OPTIONS_MAP.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>optionsStr<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">intValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>Ehr... what? I can see what happened in the developers head: "<em>Hmmm... this if statement... it's big. Yes, it's pretty ugly, it took my 10 minutes to get that right. I'll better write a comment... </em>". Unfortunately, he just made it even harder to understand.</p>
<p>After reading these examples, one might argue "<em>Complicated code is hard to explain!</em>" or "<em>It is really hard to write good comments!</em>". While these points are all valid problems, writing code is the wrong solution in my opinion. Consider the following listing, which is a revised version of the previous abomination:</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000066; font-weight: bold;">boolean</span> wildcardSearch <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;*&quot;</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>keyword<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000066; font-weight: bold;">boolean</span> validOption <span style="color: #339933;">=</span> OPTIONS_MAP.<span style="color: #006633;">containsKey</span><span style="color: #009900;">&#40;</span>optionsStr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>wildcardSearch <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span> validOption<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
options <span style="color: #339933;">=</span> getOptionKey<span style="color: #009900;">&#40;</span>optionStr<span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>This might not be perfect, and the sample doesn't make a lot of sense, but after reading those 5 lines you should be able to understand what it is that is going on. So what did I change? First of all, instead of cramming everything into one line, the code has been split up. Instead of having everything in the if statement, it is split up. Separation of concerns. Variables with telling names make it really easy to comprehend the intention: "<em>if (wildcardSearch ... ) - aaah, that makes sense</em>". It might be more to type, but I dare to say that a comment is not necessary any more.</p>
<p>Code should be self explanatory. Code should be readable like a book. If you are feeling an urge to comment the lines you just wrote, your code probably needs some refactoring. Maybe simple things like renaming variables, reformatting, maybe more complex operations like abstracting functionality away. If it really is something complex, explain the WHY this approach was taken and explain HOW it works. Be precise, be concise. Don't waste words (sample from class FooBar):</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008000; font-style: italic; font-weight: bold;">/** Class FooBar - The purpose of this class is to do XYZ... */</span><br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> FooBar <span style="color: #009900;">&#123;</span> ... <span style="color: #009900;">&#125;</span></div></div>
<p>This is one of my favorite examples. Almost an entire line of comments wasted. Empty words and phrases that don't add any value. First of all, after opening the file FooBar.java, you'll expect nothing else than class FooBar. So, the first words are unnecessary. Second, the phrase "The purpose of this class is to" doesn't carry any meaning. It's empty wordage. If you cut all the ballast away, you end up with the core of the comment:</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008000; font-style: italic; font-weight: bold;">/** Does XYZ. */</span><br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> FooBar <span style="color: #009900;">&#123;</span> ... <span style="color: #009900;">&#125;</span></div></div>
<p>Notice how the original comment of almost an entire line got boiled down to the core of the statement. Rule #17 from Elements of Style comes to mind: <em>Omit needless words</em>! To quote: "A sentence should contain no unnecessary words, a paragraph no unnecessary sentences, for the same reason that a drawing should have no unnecessary lines and a machine no unnecessary parts. " (p. 23, Elements of Style, Strunk and White). I think documenting the purpose of a class is important, but get to the point.</p>
<h2>Comments Are Still Good</h2>
<p>The above are all examples of useless comments. However, there are situations where a comment is good and necessary. If you have a public API, you'll want to explain the public methods and constructors. Consider the following questions: WHY would I use a certain constructor? WHAT is the return value of a method? HOW can I get the class to do XYZ? But as previously stated, be concise and short.</p>
<p>If you have a package for a certain purpose, write a package level package-info.java file to explain the package contents and maybe give a short sample of how to use the contained classes.</p>
<h2>Final Advice</h2>
<p>After a lot of ranting, here is a condensed list of advice.</p>
<p>What NOT to comment:</p>
<ul>
<li>The obvious. This includes getters, setters, default constructors, import statements, loggers, variable assignments,</li>
<li>Code. Remove it or keep it.</li>
</ul>
<p>What to comment:</p>
<ul>
<li>Public APIs including classes and methods.</li>
<li>High level packages.</li>
<li>If something is done in an unusual way, for example swallowing an exception: document WHY this exception doesn't need to be handled.</li>
<li>Complex algorithms (if you really are implementing one).</li>
</ul>
<p>How to avoid the necessity to write comments:</p>
<ul>
<li>Telling variable names</li>
<li>Separation of concerns</li>
<li>Use CONSTANTS!</li>
<li>Don't try to be smart. Write simple solutions. If it's so complicated that you need to document it, refactor!</li>
</ul>
<p>How to write GOOD comments:</p>
<ul>
<li>Be precise, short and concise. Don't babble.</li>
<li>Try to answer the questions that a user of your API might ask: what, why, how, when?</li>
<li>Prefer to explaining WHY something is done over WHAT or is done. WHAT is done is usually obvious.</li>
<li>If necessary, give short samples of how to use.</li>
<li>Minimize markup.</li>
<li>Get yourself a copy of <a title="Elements of Style on Amazon" href="http://www.amazon.com/Elements-Style-50th-Anniversary/dp/0205632645/ref=sr_1_1?ie=UTF8&amp;qid=1291353976&amp;sr=8-1" target="_blank">Elements of Style</a>.</li>
<li>Get yourself a copy of <a title="Clean Code" href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882" target="_blank">Clean Code</a>.</li>
<li>Check your spelling and punctuation.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.jakusys.de/blog/2010/12/my-case-against-code-comments/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Using ANTLR and Grammars for Fun and Profit</title>
		<link>http://www.jakusys.de/blog/2010/11/using-antlr-and-grammars-for-fun-and-profit/</link>
		<comments>http://www.jakusys.de/blog/2010/11/using-antlr-and-grammars-for-fun-and-profit/#comments</comments>
		<pubDate>Wed, 24 Nov 2010 03:08:45 +0000</pubDate>
		<dc:creator>Jakob Külzer</dc:creator>
				<category><![CDATA[Cool Tech]]></category>
		<category><![CDATA[ANTLR]]></category>
		<category><![CDATA[AST]]></category>
		<category><![CDATA[Grammar]]></category>
		<category><![CDATA[Lexer]]></category>
		<category><![CDATA[Parser]]></category>

		<guid isPermaLink="false">http://www.jakusys.de/blog/?p=1263</guid>
		<description><![CDATA[Recently at work I had to work on files in our legacy system. Those files, being part of a proprietary product, are unknown to any editor or pretty printer that you can find. And most of them are not formatted nicely, if at all. Being a lazy developer I really love eclipse's code formatting features, [...]]]></description>
			<content:encoded><![CDATA[<p>Recently at work I had to work on files in our legacy system. Those files, being part of a proprietary product, are unknown to any editor or pretty printer that you can find. And most of them are not formatted nicely, if at all. Being a lazy developer I really love eclipse's code formatting features, because, hey, it takes away a lot of tedious and annoying formatting. Also, I think properly formatted files are easier to understand, maintain and fix. In fact, as I recently tweeted, I go as far as saying that I'm not particularly good in spotting problems, I just format everything which helps me to understand better.<span id="more-1263"></span></p>
<p>But back to the actual problem: I had a lot of these files to look through and no tool to help me format them. So my first approach was to simply hack together a simple Java app (Yes, Java. Not Perl. Just felt like it. <img src='http://www.jakusys.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> , doing some String manipulation and indent it. However I quickly realized that my simple formatter was thrown off by multiple elements in on line. The basic format is something like this:</p>
<pre># comment
\group {
    \optionOne "value"
    \optionTwo 3.1415
    \subgroup { ... }
}</pre>
<p>Nothing to fancy. However my simple app was thrown off by something like this:</p>
<pre>\group { \anotherGroup { ...</pre>
<p>So I realized, yes, that's easy. I just need to tokenize the input stream, and when I'm at that, I can actually check for syntactically correct input. Then I remembered from my compiler classes in university that building lexers and parsers was not fun. Interesting, but just not fun. Then I remembered reading about <a title="ANTLR - ANother Tool for Language Recognition" href="http://www.antlr.org/" target="_blank">ANLTR</a>. A tool that builds lexers and parsers from a grammar. Something I always wanted to use but never found a reason to. And formatting these files, just gave me a really good reason dive in.</p>
<h2>Lexers and Parsers in a Nutshell</h2>
<p>If you are not familiar with the terms Lexers and Parsers, here's a quick rundown. Both terms are usually closely associated with compilers, because they solve a big part of the problems a compiler has to solve. A lexer, short for <em>Lexical Analyser</em>, is a program that splits an input stream based on certain rules into smaller chunks, called tokens. They are usually implemented using a regular language (<a title="Chomsky Language Hierarchy" href="http://en.wikipedia.org/wiki/Chomsky_hierarchy" target="_blank">Chomsky 3</a> to be precise) and can "recognize" simple constructs. For example, a hypothetical lexer for Java might read the following input:</p>
<pre>int i;
i = 1 + 2;</pre>
<p>and produce the following tokens (in this notation that I just made up - please note that the tokens are UPPERCASE):</p>
<pre>[ INT ] [ WHITESPACE] [ IDENTIFIER('i') ] [ SEMICOLON ] [ NEWLINE ] [ IDENTIFIER('i') ] [ WHITESPACE ] [ ASSIGNMENT ] ...</pre>
<p>Notice how every "piece" get's its own token. Comparing the tokens and the original input, it is obvious that  working with tokens is already so much easier that working with the raw text. So, now that we have tokens, what does the parser actually do? In very generic terms, the parser takes the tokens and "understands" the token stream. Or at least, he'll try to. Most parsers spend most of their lives trying to understand input and then failing because of some syntactic error. For example, you forgot a bracket in your program, or a semicolon. Take the slightly modified code from the first sample:</p>
<pre>inmt i
i = 1  2;</pre>
<p>Wow. Lot's of input that doesn't make sense, right? "<em>The word "inmt" is not a valid type identifier!</em>" you say! "<em>And the semicolons! Where are they?</em>" The experienced and weathered developer will scream in disgust: "<em>This is invalid input!</em>"   And this is where the parser comes in. A parser has a formal description of what the incoming token stream should look like. This formal description is called a grammar. A grammar is usually described in forms of "productions" which look like this very simplified sample (another notation I made up but heavily influenced by <a title="EBNF" href="http://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_Form" target="_blank">EBNF</a>):</p>
<pre>assignment -&gt; IDENTIFIER ASSIGN expression;
expression -&gt; IDENTIFIER | addition | multiplication;
addition -&gt; VALUE + VALUE;
...</pre>
<p>So, these productions map a generic concept to a more concrete concept. When the parser starts, it will match the first rule against the input, and slowly working it's way down to the most precise rules he can find (or not, if the input doesn't match the grammar). By consulting the grammar, the parser always knows what the input can contain. Usually the parser takes every production that matches and puts all of the input into a tree, the so called AST (Abstract Syntax Tree), a tree like representation of the input. For our initial sample, the (simplified) AST could look like this:</p>
<pre>           .- variable(i)
          /
program -|                  .- variable(i)
          \                /
           `- assignment -|                .- NUMERAL(1)
                           \              /
                            `- addition -| 
                                          \
                                           `- NUMERAL(2)</pre>
<p>Wow, that took me a time to "draw".</p>
<p>So, from this (simplified) AST you can see the structure of the program, right away. It is almost the pure essence of the meaning of the input code. Quite a useful and flexible mechanism. After the parser finished parsing the input tree and assuming the input was correct according to the grammar, the parser spits out a complete AST for the input. And with the AST, you can do a lot of fun and awesome things. To close the circle to my introduction, you can easily output a nicely formatted version of the input file without having to worry you might break the file. It can act as a verifier, testing whether you forgot some important input (semicolons, brackets, single or double quotes come to mind) or even translate it into something different.</p>
<p>So now you should have a really basic understanding of what a lexer and a parser does. There's a lot more to this highly interesting field. I can recommend the ANTLR Reference Guide or any of the dragon books about compilers (For some reason compiler books almost always have a dragon on them. Some say, it is because of the inherent complexity of compilers... which is probably true).</p>
<h2>ANTLR</h2>
<p>Back to my formatter/verifier for proprietary input. ANLTR takes off a lot of work from the developer because it will generate a complete lexer and parser (LL(*) parser to be precise) from a grammar for you. So all I had to do was to write a grammar for the proprietary format. Of course I don't want to keep that from you:</p>
<pre>
<div id="_mcePaste">grammar MyGrammar;</div>
<div id="_mcePaste">options {</div>
<div id="_mcePaste">    language=Java;</div>
<div id="_mcePaste">    output=AST;</div>
<div id="_mcePaste">    ASTLabelType=CommonTree;</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">WS	:	( ' ' |'\t' |'\r' )+ { $channel=HIDDEN; };</div>
<div id="_mcePaste">NL	:	'\r'? '\n' { $channel=HIDDEN; };</div>
<div id="_mcePaste">DIGITS	:	'0'..'9'+;</div>
<div id="_mcePaste">EXTRACHARS</div>
<div id="_mcePaste">:	( '/' | '\\' | '_' | '.' | ':' | '-' | '|' | '&lt;' | '&gt;' );</div>
<div id="_mcePaste">CHARS	:	('a'..'z' | 'A'..'Z')+;</div>
<div id="_mcePaste">STRING	:	'"' (CHARS | EXTRACHARS | DIGITS | WS)* '"';</div>
<div id="_mcePaste">GROUPSTART</div>
<div id="_mcePaste">:	'{';</div>
<div id="_mcePaste">GROUPEND:	'}';</div>
<div id="_mcePaste">dialog	:	entry* EOF;</div>
<div id="_mcePaste">entry	:	comment | option;</div>
<div id="_mcePaste">option	:	'/' (DIGITS | CHARS)+ (ident | group);</div>
<div id="_mcePaste">ident	:	STRING | DIGITS;</div>
<div id="_mcePaste">group	:	GROUPSTART entry* GROUPEND;</div>
<div id="_mcePaste">comment	:	'#' (CHARS | DIGITS | EXTRACHARS )*;</div>
</pre>
<p>In total it's a 33 lines with generous white space, a few comments and extra options I removed here. There's a few extra lines to load the input, and a single class that outputs a formatted file based on the generated AST. Everything else has been generated by ANTLR.</p>
<p>And suddenly I could verify and format ALL of our files using this tool. Awesome, isn't it?</p>
<h2>Final Thoughts</h2>
<p>The learning curve for an approach like this is steep. Grammars are nothing that you can pick up over night, it will require some effort to understand them and the pitfalls you can encounter (left recursive grammars, ambiguous grammars, etc etc) but the payoffs are enormous. Instead of manually formatting and manually counting opening and closing brackets in every file that I open, I can now run a simple oneliner that'll find all files and verify them for me:</p>
<pre>$ find ./ -iname '*.xxx' -exec verifier {} \;</pre>
<p>Done. All files. We have a few hundred of those, so there's some significant time savings in this little project. Also, developers are more willing to work with them now, as this little tool will always tell them if they screwed up the syntax or not.</p>
<p>All in all, I found this little exercise quite transforming. I was somewhat scared of parsers and compilers, just because it's hard to build them in a good way. But now, given the power of ANTLR and the grammar driven approach, I start to see new solutions for a lot of problems.</p>
<p>Therefore my advice: go and learn about grammars and play with ANTLR. It can make your life so much easier.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jakusys.de/blog/2010/11/using-antlr-and-grammars-for-fun-and-profit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Playing with AS3 Low Level Graphics</title>
		<link>http://www.jakusys.de/blog/2010/05/playing-with-as3-low-level-graphics/</link>
		<comments>http://www.jakusys.de/blog/2010/05/playing-with-as3-low-level-graphics/#comments</comments>
		<pubDate>Wed, 12 May 2010 00:05:59 +0000</pubDate>
		<dc:creator>Jakob Külzer</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.jakusys.de/blog/?p=1246</guid>
		<description><![CDATA[I've been toying around with the low level graphics API after seeing Ralph Hauwerts awesome presentation at the FITC. (I'm still waiting for my tshirt though). He demoed an application using particles doing all those fancy things and I wanted to try that myself. I'm still working on it and it's not as cool as [...]]]></description>
			<content:encoded><![CDATA[<p>I've been toying around with the low level graphics API after seeing <a title="Ralph Hauwerts Blog" href="http://www.unitzeroone.com/blog/">Ralph Hauwerts</a> awesome presentation at the FITC. (I'm still waiting for my tshirt though). He demoed an application using particles doing all those fancy things and I wanted to try that myself. I'm still working on it and it's not as cool as Ralph's demo, but my first experiments turned out to look kinda cool too. Enjoy.</p>
<p><span id="more-1246"></span></p>
<p>In the first SWF I just tried to get the basic code working, randomly moving particles, multiple colors and a nice blur effect. Looks cool, but turns black as the blur effect sums up (reload if its black already):</p>

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_0" width="400" height="300">
      <param name="movie" value="http://www.jakusys.de/blog/wp-content/uploads/2010/05/particles_white_to_black.swf" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://www.jakusys.de/blog/wp-content/uploads/2010/05/particles_white_to_black.swf" width="400" height="300">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>

<p>My next attempt is better. I used a ColorTransform to slowly increase the color values which gives this nice animation:</p>

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_1" width="400" height="300">
      <param name="movie" value="http://www.jakusys.de/blog/wp-content/uploads/2010/05/particles.swf" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://www.jakusys.de/blog/wp-content/uploads/2010/05/particles.swf" width="400" height="300">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>

<p>Amazing what can be done in an hour of playing around with Flash's drawing API and bitmap manipulation.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jakusys.de/blog/2010/05/playing-with-as3-low-level-graphics/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Aktualisiert: Vortragsfolien</title>
		<link>http://www.jakusys.de/blog/2010/03/vortragsfolien/</link>
		<comments>http://www.jakusys.de/blog/2010/03/vortragsfolien/#comments</comments>
		<pubDate>Fri, 19 Mar 2010 15:23:26 +0000</pubDate>
		<dc:creator>Jakob Külzer</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.jakusys.de/blog/?p=1239</guid>
		<description><![CDATA[Die Vortragsfolien zu meinem Vortrag über RIAs, Flex und Mate: Rich Internet Applications, Flex and Mate Hier gibt es die Code Samples!]]></description>
			<content:encoded><![CDATA[<p>Die Vortragsfolien zu meinem Vortrag über RIAs, Flex und Mate: <a href="http://www.jakusys.de/blog/wp-content/uploads/2010/03/presentation.pdf">Rich Internet Applications, Flex and Mate</a></p>
<p>Hier gibt es die <a href="http://www.jakusys.de/blog/wp-content/uploads/2010/03/code_samples.zip">Code Samples!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jakusys.de/blog/2010/03/vortragsfolien/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building a CMS using XML, XSLT, Ant and ImageMagick</title>
		<link>http://www.jakusys.de/blog/2010/01/building-a-cms-using-xml-xslt-ant-and-imagemagik/</link>
		<comments>http://www.jakusys.de/blog/2010/01/building-a-cms-using-xml-xslt-ant-and-imagemagik/#comments</comments>
		<pubDate>Sun, 03 Jan 2010 12:17:28 +0000</pubDate>
		<dc:creator>Jakob Külzer</dc:creator>
				<category><![CDATA[Cool Tech]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[AIR]]></category>
		<category><![CDATA[Ant]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[ImageMagik]]></category>
		<category><![CDATA[Saxon]]></category>
		<category><![CDATA[Webdevelopment]]></category>
		<category><![CDATA[XHTML]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[XSLT]]></category>
		<category><![CDATA[XSLT2.0]]></category>

		<guid isPermaLink="false">http://www.jakusys.de/blog/?p=1051</guid>
		<description><![CDATA[Not so long ago a freelance client approached me with some updates for their website. The site has been growing organically since 2000 and therefore was a big mess. Several attempts to port the site to a CMS driven system failed largely because those CMS systems are usually to complex for our needs (Typo3) or [...]]]></description>
			<content:encoded><![CDATA[<p>Not so long ago a freelance client approached me with some updates for their website. The site has been growing organically since 2000 and therefore was a big mess. Several attempts to port the site to a CMS driven system failed largely because those CMS systems are usually to complex for our needs (Typo3) or not flexible enough (Joomla, WordPress). So as I was faced with updates to all the updates including image updates which in turn needed thumbnails to be generated. The same day I stumbled randomly over the <a href="http://www.w3.org/TR/xslt20/" target="_blank">xsl:result-document</a> function in XSLT 2.0 which allows you to transform a single XML file into several output files. That sparked an idea with me: why not use that to build a CMS system using XML technologies? I've toyed around with <a title="Apache Cocoon" href="http://cocoon.apache.org/" target="_blank">Cocoon</a> a couple of years ago but that was not what I was looking for. So I looked for other technologies...</p>
<p>This post is a write-down of my experiences building a XML/XSLT driven simple CMS system. In it I will show you the required technologies, my approaches and my solutions to problems I've encountered. You'll need a solid understanding of XML at least, understanding of Ant and XSLT helps a lot, too.</p>
<p>This post contains tons of XML and I tried my best to format it in a readable way — in fact I've spent hours to get everything nicely on the screen.<br />
<span id="more-1051"></span></p>
<h2>Requirements to the CMS</h2>
<p>I had several objectives when I built my system:</p>
<ul>
<li>All mundane and repetitive tasks should be automated, including thumbnail generation, creation of a global navigation, synchronizing with a live site</li>
<li>Flexible enough to support new "content types" and new views</li>
<li>Versionable with Git, Subversion or other SCMs</li>
<li>Creation of output artifacts should be a single command</li>
</ul>
<h2>Technologies</h2>
<p>The most prominent and important technology I used is XSLT 2.0. If you don't know what XSLT is, here is XSLT in a nutshell.</p>
<p>XSLT stands for eXtensible Stylesheet Language Transformations. What it does is surprisingly simple. It takes a piece of XML as input (aka source tree or input tree), applies some transformations on it and outputs a new piece of XML. Sounds simple in theory, however in practice it is usually somewhat more complicated because XSLT is a functional language and sometimes requires you to solve problems backwards and don't even get me started on <a href="http://www.w3.org/TR/xml-names11/" target="_blank">XML namespaces</a>...</p>
<p>Traditionally you'd have one input XML file, one XSL stylesheet and accordingly one single XML output file. However with the new xsl:result-document I can suddenly output into several files.</p>
<p>As I'm using XSLT the next technology used is XML of course. Not much to say about this except that it is involved in pretty much every step. To bind everything together I'm using <a title="Apache Ant" href="http://ant.apache.org/" target="_blank">Apache Ant</a>, an incredibly flexible tool. Interestingly enough Ant uses XML files for its build files which comes in handy later on. Also it solves one of my requirements: it is just plain text and therefor versionable.</p>
<p>Last there is image manipulation. I've experimented a bit with the Ant image tasks that use JAI to perform manipulation but quickly dropped that approach as this task won't even let you specify a quality parameter for image manipulations. I've ended up using an old friend: <a title="ImageMagick" href="http://www.imagemagick.org/script/index.php" target="_blank">ImageMagick</a>. ImageMagick is an amazing toolkit of versatile command line tools to modify images. It allows to modify images in many different ways from resizing to color correction or combining them.</p>
<h2>Basic Structure</h2>
<p>The basic structure of an XML/XSLT driven CMS contains one or more XML files that contain the "raw" data for the website, XSLT to transform it into XHTML and assets. More on assets later.</p>
<h3>The XML Part</h3>
<p>The XML file used in my project is a very simple one. It defines "pages" that get translated into real HTML pages. Each page has a section called contents which in turn contain the actual page contents. Let's have a look at a short sample:</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br /></div></td><td><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;utf-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:site</span> <span style="color: #000066;">title</span>=<span style="color: #ff0000;">&quot;My XSLT Generated website&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">xmlns:s</span>=<span style="color: #ff0000;">&quot;http://www.jakusys.de/xslt-cms&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/1999/xhtml&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:page</span> <span style="color: #000066;">title</span>=<span style="color: #ff0000;">&quot;Home&quot;</span> <span style="color: #000066;">filename</span>=<span style="color: #ff0000;">&quot;index.html&quot;</span> <span style="color: #000066;">showTitle</span>=<span style="color: #ff0000;">&quot;false&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:contents<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:html<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;h1<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Welcome to my XSLT generated page!<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/h1<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;p<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Bla bla bla <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/p<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/s:html<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/s:contents<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/s:page<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:page</span> <span style="color: #000066;">title</span>=<span style="color: #ff0000;">&quot;Contact Me&quot;</span> <span style="color: #000066;">filename</span>=<span style="color: #ff0000;">&quot;contactme.html&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:contents<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:html<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;h1<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Contact Me<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/h1<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;p<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Send me an <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;a</span> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">&quot;&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>email<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/a<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>!<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/p<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/s:html<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/s:contents<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/s:page<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/s:site<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></td></tr></tbody></table></div>
<p>Well, so far nothing impressive. Actually it looks like more work compared to typing out the actual pages themselves. But behold, here comes the stylesheet to actually turn the above XML into nice websites (XHTML):</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br /></div></td><td><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:stylesheet</span> <span style="color: #000066;">xmlns:xsl</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/1999/XSL/Transform&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;2.0&quot;</span> <span style="color: #000066;">exclude-result-prefixes</span>=<span style="color: #ff0000;">&quot;#all&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/1999/xhtml&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">xpath-default-namespace</span>=<span style="color: #ff0000;">&quot;http://www.jakusys.de/&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:output</span> <span style="color: #000066;">method</span>=<span style="color: #ff0000;">&quot;html&quot;</span> <span style="color: #000066;">indent</span>=<span style="color: #ff0000;">&quot;yes&quot;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;html&quot;</span> </span><br />
<span style="color: #009900;"> &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">omit-xml-declaration</span>=<span style="color: #ff0000;">&quot;yes&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
<br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:template</span> <span style="color: #000066;">match</span>=<span style="color: #ff0000;">&quot;/&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:apply-templates</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;site&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:template<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:template</span> <span style="color: #000066;">match</span>=<span style="color: #ff0000;">&quot;site&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:apply-templates</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;page&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:template<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:template</span> <span style="color: #000066;">match</span>=<span style="color: #ff0000;">&quot;page&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:variable</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;filename&quot;</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;@filename&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:result-document</span> <span style="color: #000066;">omit-xml-declaration</span>=<span style="color: #ff0000;">&quot;yes&quot;</span> <span style="color: #000066;">indent</span>=<span style="color: #ff0000;">&quot;yes&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">href</span>=<span style="color: #ff0000;">&quot;{$filename}&quot;</span> <span style="color: #000066;">format</span>=<span style="color: #ff0000;">&quot;html&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">doctype-public</span>=<span style="color: #ff0000;">&quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">doctype-system</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;html</span> <span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/1999/xhtml&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;head<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">http-equiv</span>=<span style="color: #ff0000;">&quot;Content-Type&quot;</span> </span><br />
<span style="color: #009900;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;text/html; charset=utf-8&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:value-of</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;@title&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/head<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;container&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:apply-templates</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;contents/*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/html<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:result-document<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:template<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<br />
&nbsp; &nbsp; &nbsp;<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:template</span> <span style="color: #000066;">match</span>=<span style="color: #ff0000;">&quot;*&quot;</span> <span style="color: #000066;">mode</span>=<span style="color: #ff0000;">&quot;html&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:copy</span> <span style="color: #000066;">copy-namespaces</span>=<span style="color: #ff0000;">&quot;no&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:copy-of</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;@*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:apply-templates</span> <span style="color: #000066;">mode</span>=<span style="color: #ff0000;">&quot;html&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:copy<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp;<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:template<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:stylesheet<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></td></tr></tbody></table></div>
<p>Now it get's more interesting. Let's dissect what the above XSLT does. The blocks in line 10 to 12 are a template that matches the root level element in the source XML tree. All it does is to call the next matching stylesheets which are in lines 14 to 19. This template does exactly the same and passes on. Then we reach line 18 with the template matching page elements.</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>18<br />19<br />20<br />21<br />22<br />23<br /></div></td><td><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:variable</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;filename&quot;</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;@filename&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:result-document</span> <span style="color: #000066;">omit-xml-declaration</span>=<span style="color: #ff0000;">&quot;yes&quot;</span> </span><br />
<span style="color: #009900;"> &nbsp; <span style="color: #000066;">indent</span>=<span style="color: #ff0000;">&quot;yes&quot;</span> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">&quot;{$filename}&quot;</span> <span style="color: #000066;">format</span>=<span style="color: #ff0000;">&quot;html&quot;</span> </span><br />
<span style="color: #009900;"> &nbsp; <span style="color: #000066;">doctype-public</span>=<span style="color: #ff0000;">&quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot;</span> </span><br />
<span style="color: #009900;"> &nbsp; <span style="color: #000066;">doctype-system</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;</span> </span><br />
<span style="color: #009900;"> &nbsp; <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span></div></td></tr></tbody></table></div>
<p>Line 18 defines a variable called filename which is prefilled with with the filename attribute from the XML page element. The next line sports the so much praised (at least by me) xsl:result-document element. If you read the line it gets clear very fast that it should output a new HTML file (format="html" href="$filename"), nicely formatted (indent="yes") and with the appropriate DOCTYPE declaration. The  next lines are just an HTML boilerplate with head and content type. Please note that this is a very minimalistic example. Usually you would include stylesheets, JavaScript includes and other additional headers there. For simplicity they are omitted.</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>28<br />29<br />30<br /></div></td><td><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:value-of</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;@title&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span> - <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:value-of</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;/site/@title&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></td></tr></tbody></table></div>
<p>Lines 28 to 31 output a new title tag populated with the title attribute from our source attribute. Convenient. The CMS is starting to take shape.</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>33<br />34<br />35<br /></div></td><td><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;container&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:apply-templates</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;contents/*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></td></tr></tbody></table></div>
<p>And finally lines 33 to 35 will call another template lines 41 to 46 which just copies the HTML into the output document.</p>
<p>So far so good. What have we achieved? The stylesheet creates a new page based on boilerplate HTML - which can be arbitrarily complex with CSS stylesheets, JavaScript and more - and pre-fills the title and the actual body. Now let's add more functionality. Every good website needs a navigation. We can achieve that easily by adding another template that matches all page elements. We add a few new lines to the boilerplate HTML:</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;navigation&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ul<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:apply-templates</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;/site/page&quot;</span> <span style="color: #000066;">mode</span>=<span style="color: #ff0000;">&quot;navigation&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ul<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p>Looks simple enough. This will output a new DIV, fill it with a unordered list and calls another template.  The interesting part is the select attribute: it tells the XSLT processor to select all root level page elements. Now let's have a look at how the called template looks like:</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:template</span> <span style="color: #000066;">match</span>=<span style="color: #ff0000;">&quot;page&quot;</span> <span style="color: #000066;">mode</span>=<span style="color: #ff0000;">&quot;navigation&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;li<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;a</span> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">&quot;{@filename}&quot;</span> <span style="color: #000066;">title</span>=<span style="color: #ff0000;">&quot;{@title}&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:value-of</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;@title&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/a<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/li<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:template<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p>The XSLT processor will translate this into global navigation of our site. All top level pages will be listed with the correct title and the correct filename.</p>
<h3>The Ant Part</h3>
<p>Now that we have the stylesheets and the input XML files in place, we'll need an elegant way to transform the whole site with on simple command. As discussed earlier Ant is a good choice for this. I won't delve into the actual ANT buildfile as it is pretty straightforward. What I want to show is how to use XSLT to generate ANT buildfiles from other XML. This is actually a pretty powerful technique as I can custom tailor ANT files to whatever need I have. In this particular example I want to show how to create image thumbnails.</p>
<p>Here is what we have. In our input XML file, we reference images. For those images, let's say, product shots, we have the originals lying in some location in the filesystem. Those images need to be scaled down to a high res view (800×600) and to a thumbnail (128×128). We could do that with an ANT pathmatcher, but that would just take all the images it can find, not just the referenced ones. Bad and slow. And how do we keep the build directory free of old and unused pictures then?</p>
<p>What we'll do instead is we'll take the input XML file, create a XSLT stylesheet that will grab all the image references and put them into a custom ANT build file which in turn calls an image manipulation program (ImageMagick) to scale down the pictures. There's a few other goodies in here too, e.g. automatic file name cleanup. Here is the images.xsl:</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br /></div></td><td><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:stylesheet</span> <span style="color: #000066;">xmlns:xsl</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/1999/XSL/Transform&quot;</span> </span><br />
<span style="color: #009900;"> &nbsp; <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;2.0&quot;</span> <span style="color: #000066;">xpath-default-namespace</span>=<span style="color: #ff0000;">&quot;http://www.jakusys.de/&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:output</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span> <span style="color: #000066;">method</span>=<span style="color: #ff0000;">&quot;xml&quot;</span> <span style="color: #000066;">indent</span>=<span style="color: #ff0000;">&quot;yes&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
<br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:template</span> <span style="color: #000066;">match</span>=<span style="color: #ff0000;">&quot;/&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;project</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;Image Processing&quot;</span> <span style="color: #000066;">default</span>=<span style="color: #ff0000;">&quot;prepare-images&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;prepare-images&quot;</span> <span style="color: #000066;">depends</span>=<span style="color: #ff0000;">&quot;copy-originals,scale&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span> <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;copy-originals&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:element</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;copy&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:attribute</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;todir&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:text<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>${build.dir}/images<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:text<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:attribute<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:element</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;fileset&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:attribute</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;dir&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:text<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>${assets.dir}/images<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:text<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:attribute<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:apply-templates</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;//image&quot;</span> <span style="color: #000066;">mode</span>=<span style="color: #ff0000;">&quot;copy-original&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:element<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:element<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> &nbsp; <br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;scale&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:apply-templates</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;//image&quot;</span> <span style="color: #000066;">mode</span>=<span style="color: #ff0000;">&quot;thumbnail&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/project<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:template<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:template</span> <span style="color: #000066;">match</span>=<span style="color: #ff0000;">&quot;image&quot;</span> <span style="color: #000066;">mode</span>=<span style="color: #ff0000;">&quot;thumbnail&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;exec</span> <span style="color: #000066;">executable</span>=<span style="color: #ff0000;">&quot;/opt/local/bin/convert&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;arg</span> <span style="color: #000066;">line</span>=<span style="color: #ff0000;">&quot;-thumbnail 128x128 -quality 0.85 assets/images/{@src}.jpg build/images/{lower-case(@src)}_thumb.jpg&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/exec<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:template<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:template</span> <span style="color: #000066;">match</span>=<span style="color: #ff0000;">&quot;image&quot;</span> <span style="color: #000066;">mode</span>=<span style="color: #ff0000;">&quot;copy-original&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;include</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;{lower-case(@src)}.jpg&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:template<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:stylesheet<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></td></tr></tbody></table></div>
<h2>Google Sitemaps</h2>
<p>Most people that have used Google's Webmaster Tools know about the sitemap. No need to write them manually any more, you can easily use the XML representation and a XSLT stylesheet to generate it for you:</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br /></div></td><td><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:stylesheet</span> <span style="color: #000066;">xmlns:xsl</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/1999/XSL/Transform&quot;</span> </span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;2.0&quot;</span> <span style="color: #000066;">xpath-default-namespace</span>=<span style="color: #ff0000;">&quot;http://www.jakusys.de/&quot;</span> </span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://www.sitemaps.org/schemas/sitemap/0.9&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:output</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span> <span style="color: #000066;">method</span>=<span style="color: #ff0000;">&quot;xml&quot;</span> <span style="color: #000066;">indent</span>=<span style="color: #ff0000;">&quot;yes&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
<br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:template</span> <span style="color: #000066;">match</span>=<span style="color: #ff0000;">&quot;/&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;urlset</span> <span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://www.sitemaps.org/schemas/sitemap/0.9&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:apply-templates</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;site/page&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/urlset<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:template<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:template</span> <span style="color: #000066;">match</span>=<span style="color: #ff0000;">&quot;page&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;url<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;loc<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>http://www.my-website.com/<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:value-of</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;@filename&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/loc<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;lastmod<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>2009-09-10<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/lastmod<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;changefreq<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>monthly<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/changefreq<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/url<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:template<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:stylesheet<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></td></tr></tbody></table></div>
<h2>Issues</h2>
<p>So with all the technologies in place, I ran into some issues but all of them could be solved quickly. I'm listing them here hoping they'll help other people.</p>
<h3>XSLT 2.0 with Ant</h3>
<p>This one was most annoying. Per default Ant has an <a title="Apache Ant XSLT" href="http://ant.apache.org/manual/CoreTasks/style.html" target="_blank">xslt-task</a> which allows you to transform XML but it is limited to XSLT 1.0. If you read the documentation you'll find out that you can plug in different XSLT processors but you are still quite limited. If you want to use XSLT 2.0 with Ant get the amazing <a title="Saxon XML Processor" href="http://saxon.sourceforge.net/" target="_blank">Saxon processor</a> and use their Ant task which is a bit hidden on their page. Get it from the Sourceforge <a title="Saxon Ant Task" href="http://sourceforge.net/projects/saxon/files/saxon%20ant%20task/" target="_blank">download site</a>. This task lets you leverage the full functionality of XSLT 2.0 including the xsl:result-document.</p>
<p>All you have to do to get it working is to copy the required JARs into the classpath, declare the custom task and use it:</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;taskdef</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;saxon-xslt&quot;</span> <span style="color: #000066;">classname</span>=<span style="color: #ff0000;">&quot;net.sf.saxon.ant.AntTransform&quot;</span> </span><br />
<span style="color: #009900;"> &nbsp; <span style="color: #000066;">classpath</span>=<span style="color: #ff0000;">&quot;lib/saxon9he.jar;lib/saxon9-ant.jar&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span></div></td></tr></tbody></table></div>
<p>Now you can use the saxon-xslt task:</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;transform&quot;</span> <span style="color: #000066;">depends</span>=<span style="color: #ff0000;">&quot;init&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp;<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;saxon-xslt</span> <span style="color: #000066;">in</span>=<span style="color: #ff0000;">&quot;${xml}&quot;</span> <span style="color: #000066;">style</span>=<span style="color: #ff0000;">&quot;${xsl}&quot;</span> <span style="color: #000066;">out</span>=<span style="color: #ff0000;">&quot;${build.dir}/output.html&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp;<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></td></tr></tbody></table></div>
<h3>XML Namespaces in HTML</h3>
<p>This was a tricky one. The problem was that in my custom XML I had snippets of HTML which I wanted to mirror into the output documents. I used the xsl:copy-of function which basically did what it was supposed to. It copied the (X)HTML over but by doing so, it had to adjust the namespaces for the XML. The input document had no namespace declarations at all and the output document was bound to the XHTML namespace. So the processor did exactly what it is supposed to: it added null namespace  declarations to the copied elements which looked like this:</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;p</span> <span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;null&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Bla bla bla<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/p<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></td></tr></tbody></table></div>
<p>Not a problem per se but unfortunately invalid XHTML. The solution to this problem is surprisingly simple: Add namespace declarations to the input document:</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;utf-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:site</span> <span style="color: #000066;">title</span>=<span style="color: #ff0000;">&quot;My XSLT Generated website&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">xmlns:s</span>=<span style="color: #ff0000;">&quot;http://www.jakusys.de/xslt-cms&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/1999/xhtml&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span></div></td></tr></tbody></table></div>
<p>The above lines will put the input document per default into the XHTML namespace and everything else in my own, personal namespace. Regular (X)HTML markup however does not get any namespace prefixes, so it will be put into the XHTML namespace:</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:page</span> <span style="color: #000066;">title</span>=<span style="color: #ff0000;">&quot;Home&quot;</span> <span style="color: #000066;">filename</span>=<span style="color: #ff0000;">&quot;index.html&quot;</span> <span style="color: #000066;">showTitle</span>=<span style="color: #ff0000;">&quot;false&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:contents<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:html<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;h1<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Welcome to my XSLT generated page!<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/h1<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/s:html<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/s:contents<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/s:page<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></td></tr></tbody></table></div>
<h2>Conclusion</h2>
<p>The one big problem I still have with this system is that it does not support hierarchical pages yet. But if the need arises it could be added without too much effort. Another moose with the system is that it still requires editing XML which is neither user-friendly nor easy for non technical users. But one could easily create a Flex or AIR app to modify and edit those files. Thanks to Flex' really good XML support it should not be hard to do that. I could even think of a Grails Webapp generating the XML for this (using the brilliant XML markup builder).</p>
<p>In general it is a really powerful and flexible system. As I am running this on a UNIX system I can harness all the tools and goodies that are there. Ant and Java give me whatever power and libraries I need. So I can steer this thing in whichever direction I want.</p>
<p>If you have any questions feel free to comment below or drop me an email.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jakusys.de/blog/2010/01/building-a-cms-using-xml-xslt-ant-and-imagemagik/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Liquibase Incremental DB Diff</title>
		<link>http://www.jakusys.de/blog/2009/12/liquibase-incremental-db-diff/</link>
		<comments>http://www.jakusys.de/blog/2009/12/liquibase-incremental-db-diff/#comments</comments>
		<pubDate>Sat, 12 Dec 2009 15:14:24 +0000</pubDate>
		<dc:creator>Jakob Külzer</dc:creator>
				<category><![CDATA[Grails]]></category>
		<category><![CDATA[#ggx]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Groovy & Grails Exchange]]></category>
		<category><![CDATA[LiquiBase]]></category>
		<category><![CDATA[Migration]]></category>
		<category><![CDATA[Schema]]></category>

		<guid isPermaLink="false">http://www.jakusys.de/blog/?p=1112</guid>
		<description><![CDATA[After discussing this on the Groovy and Grails Exchange, I finally put together a new version of the db diff script that I've mentioned in an earlier post. I couldn't find the original version that I've written a couple of months ago, so I hacked together a new one. It's far from perfect, efficient or [...]]]></description>
			<content:encoded><![CDATA[<p>After discussing this on the Groovy and Grails Exchange, I finally put together a new version of the db diff script that I've mentioned in an earlier post. I couldn't find the original version that I've written a couple of months ago, so I hacked together a new one. It's far from perfect, efficient or beautiful, but it does what it is supposed to.</p>
<p>So, what's the idea behind this script? Everybody that uses Liquibase (if you are not, check out my blog post about <a title="Liqiubase and Grails - How to use it" href="http://www.jakusys.de/blog/2008/09/grails-and-liquibase-how-to-use/" target="_blank">what Liquibase is and how to use it</a>) knows how painful it is to update your changelog.xml. Liquibase already gives you a great tool to start with, the db-diff command. However, it is hardcoded to diff the current environment's database against the test database. This is annoying as you'll have to modify your datasources and keep the database schema updated manually. But fear not, here is my (surprisingly) easy solution.</p>
<p>I've created a simple script (or rather, I took the db-diff script and hacked it), which I've called incremental DB diff (all the other cool names are already taken...) and what it does is the following:</p>
<ol>
<li> update the schema in the db-diff (or whatever you call it) database using the changelog.xml</li>
<li>diff the database of the current environment against this database and output the diff as Liquibase XML</li>
</ol>
<p>So, how is this a good thing? Easy: this little script will automatically create a target database to diff against using the changelog.xml which is good, as the changelog.xml represents your last migration status. And as it uses a separate database it doesn't influence the test database.</p>
<p>After running the script just put the output in the changelog.xml and you're done.</p>
<p>All you have to do to use this is to drop the file into your /scripts/ directory, create a new database and an according datasource entry for the environment "dbdiff" like this:</p>
<pre>	dbdiff {
		dataSource {
			driverClassName = "com.mysql.jdbc.Driver"
			dbCreate = "create-drop"
			url = "jdbc:mysql://localhost/foo_dbdiff"
			username = "foo"
			password = "bar"
		}
	}</pre>
<p>Download <a href="http://www.jakusys.de/files/DbDiffIncremental.groovy" target="_blank">DbDiffIncremental.groovy</a>. Drop me a mail or a comment if you have questions.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jakusys.de/blog/2009/12/liquibase-incremental-db-diff/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Grails GraniteDS Plugin and Flex Modules &#8211; Could not resolve ? to a component implementation</title>
		<link>http://www.jakusys.de/blog/2009/10/grails-graniteds-plugin-and-flex-modules-could-not-resolve-to-a-component-implementation/</link>
		<comments>http://www.jakusys.de/blog/2009/10/grails-graniteds-plugin-and-flex-modules-could-not-resolve-to-a-component-implementation/#comments</comments>
		<pubDate>Fri, 02 Oct 2009 19:30:00 +0000</pubDate>
		<dc:creator>Jakob Külzer</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Flex Modules]]></category>
		<category><![CDATA[Gotcha]]></category>
		<category><![CDATA[GraniteDS]]></category>

		<guid isPermaLink="false">http://www.jakusys.de/blog/?p=1107</guid>
		<description><![CDATA[I'm currently working a lot with the Grails GraniteDS plugin. Just recently I've started to separate my application into modules and ran into a really nasty error. It took me some time to figure it out, hopefully I can save you from going through all this. The Flex web tier compiler usually gives me this [...]]]></description>
			<content:encoded><![CDATA[<p>I'm currently working a lot with the Grails GraniteDS plugin. Just recently I've started to separate my application into modules and ran into a really nasty error.</p>
<p>It took me some time to figure it out, hopefully I can save you from going through all this.</p>
<p>The Flex web tier compiler usually gives me this error:</p>
<pre>Error: Could not resolve &lt;namespace:Component&gt; to a component implementation.

 &lt;namespace:Component/&gt;

error during compilation Could not resolve &lt;namespace:Component&gt; to a component implementation.</pre>
<p>Initial research confirmed what I thought, this error is caused by a mismatch between a XML namespace declaration and the actual location of a component. However the location and the namespace declaration looked right and the issue occurred only <strong>after</strong> I had moved the questionable component into a separate module.</p>
<p>After two painful hours I realized that the Flex webtier compiler, as configured with GraniteDS, <strong>resolves namespaces relative to modules, not relative to the source folder</strong>. D'oh!</p>
<p>The solution I came up with was simple, might be naïve though. I figured that if resolution is relative to the Module and not to the source folder, there might be no such source folder as I would expect it. A quick look into the flex-config.xml found in &lt;GRAILS_PROJ&gt;/web-app/WEB-INF/flex/flex-config.xml confirmed this:</p>
<pre>&lt;!-- List of path elements that form the roots of ActionScript class hierarchies. --&gt;
<strong> &lt;!-- not set --&gt;</strong>
 &lt;!--
 &lt;source-path&gt;
 &lt;path-element&gt;string&lt;/path-element&gt;
 &lt;/source-path&gt;
 --&gt;</pre>
<p>So there is no explicit source path set. So I changed it so it would point to &lt;GRAILS_PROJ&gt;/grails-app/views/flex:</p>
<pre>&lt;!-- List of path elements that form the roots of ActionScript class hierarchies. --&gt;
 &lt;!-- not set --&gt;
 &lt;source-path&gt;
<strong> &lt;path-element&gt;../../../grails-app/views/flex&lt;/path-element&gt;</strong>
 &lt;/source-path&gt;</pre>
<p>Voilá - it works. However, as mentioned earlier, this might be a very limited solution, but for now it works.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jakusys.de/blog/2009/10/grails-graniteds-plugin-and-flex-modules-could-not-resolve-to-a-component-implementation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Panorama – Château Villandry II</title>
		<link>http://www.jakusys.de/blog/2009/09/panorama-%e2%80%93-chateau-villandry-ii/</link>
		<comments>http://www.jakusys.de/blog/2009/09/panorama-%e2%80%93-chateau-villandry-ii/#comments</comments>
		<pubDate>Fri, 25 Sep 2009 22:45:05 +0000</pubDate>
		<dc:creator>Jakob Külzer</dc:creator>
				<category><![CDATA[Panorama]]></category>
		<category><![CDATA[Travel]]></category>
		<category><![CDATA[France]]></category>
		<category><![CDATA[Hugin]]></category>
		<category><![CDATA[Photography]]></category>
		<category><![CDATA[Val de Loires]]></category>
		<category><![CDATA[Villandry]]></category>

		<guid isPermaLink="false">http://www.jakusys.de/blog/?p=1102</guid>
		<description><![CDATA[And here is my second panorama from Château de Villandry. This particular one has been made from the stairs leading to the vegetable gardens.]]></description>
			<content:encoded><![CDATA[<p>And here is my second panorama from Château de Villandry. This particular one has been made from the stairs leading to the vegetable gardens.</p>
<div id="attachment_1103" class="wp-caption alignnone" style="width: 310px"><a href="http://www.jakusys.de/blog/wp-content/uploads/2009/09/stitch01.jpg" rel="lightbox[1102]"><img class="size-medium wp-image-1103" title="Vegetable Gardens at Château de Villandry " src="http://www.jakusys.de/blog/wp-content/uploads/2009/09/stitch01-300x78.jpg" alt="Vegetable Gardens at Château de Villandry" width="300" height="78" /></a><p class="wp-caption-text">Vegetable Gardens at Château de Villandry</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.jakusys.de/blog/2009/09/panorama-%e2%80%93-chateau-villandry-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Panorama &#8211; Château Villandry</title>
		<link>http://www.jakusys.de/blog/2009/09/panorama-chateau-villandry/</link>
		<comments>http://www.jakusys.de/blog/2009/09/panorama-chateau-villandry/#comments</comments>
		<pubDate>Tue, 22 Sep 2009 16:50:10 +0000</pubDate>
		<dc:creator>Jakob Külzer</dc:creator>
				<category><![CDATA[Panorama]]></category>
		<category><![CDATA[Travel]]></category>
		<category><![CDATA[France]]></category>
		<category><![CDATA[Photography]]></category>
		<category><![CDATA[Val de Loires]]></category>
		<category><![CDATA[Villandry]]></category>

		<guid isPermaLink="false">http://www.jakusys.de/blog/?p=1093</guid>
		<description><![CDATA[I finally managed to create my panorama from Château Villandry in France. I missed one image so there's an ugly gray border on the bottom left. Other than that it's a really beautiful panorama, you can see almost all the gardens. Enjoy. (Click for high-res version!)]]></description>
			<content:encoded><![CDATA[<p>I finally managed to create my panorama from <a href="http://www.chateauvillandry.com/" target="_blank">Château Villandry</a> in France. I missed one image so there's an ugly gray border on the bottom left. Other than that it's a really beautiful panorama, you can see almost all the gardens. Enjoy. (Click for high-res version!)</p>
<div id="attachment_1096" class="wp-caption alignnone" style="width: 310px"><a href="http://www.jakusys.de/blog/wp-content/uploads/2009/09/stitch02.jpg" rel="lightbox[1093]"><img class="size-medium wp-image-1096" title="Panorama of Château Villandry and its Gardens" src="http://www.jakusys.de/blog/wp-content/uploads/2009/09/stitch02-300x97.jpg" alt="Panorama of Château Villandry and its Gardens" width="300" height="97" /></a><p class="wp-caption-text">Panorama of Château Villandry and its Gardens</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.jakusys.de/blog/2009/09/panorama-chateau-villandry/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

