<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type='text/xsl' href='http://dnovatchev.spaces.live.com/mmm2008-04-25_07.02/rsspretty.aspx?rssquery=en-US;http%3a%2f%2fdnovatchev.spaces.live.com%2ffeed.rss' version='1.0'?><rss version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:msn="http://schemas.microsoft.com/msn/spaces/2005/rss" xmlns:live="http://schemas.microsoft.com/live/spaces/2006/rss" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:cf="http://www.microsoft.com/schemas/rss/core/2005" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>XSLT: Riding the challenge</title><description>All the things you thought impossible to do with XSLT</description><link>http://dnovatchev.spaces.live.com/</link><language>en-US</language><pubDate>Sun, 11 May 2008 03:19:49 GMT</pubDate><lastBuildDate>Sun, 11 May 2008 03:19:49 GMT</lastBuildDate><generator>Microsoft Spaces v1.1</generator><docs>http://www.rssboard.org/rss-specification</docs><ttl>60</ttl><live:identity><live:id>4949635400605856904</live:id><live:alias>dnovatchev</live:alias></live:identity><cf:listinfo><cf:group ns="http://schemas.microsoft.com/live/spaces/2006/rss" element="typelabel" label="Type" /><cf:group ns="http://schemas.microsoft.com/live/spaces/2006/rss" element="tag" label="Tag" /><cf:group element="category" label="Category" /><cf:sort element="pubDate" label="Date" data-type="date" default="true" /><cf:sort element="title" label="Title" data-type="string" /><cf:sort ns="http://purl.org/rss/1.0/modules/slash/" element="comments" label="Comments" data-type="number" /></cf:listinfo><item><title>Jeni's "Grouper" (or how to specify and parse additional rules to a grammar) is just a minor task for LBNF</title><link>http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!438.entry</link><description>&lt;p&gt;&lt;font size=2&gt;In her recent post &amp;quot;&lt;a href="http://www.jenitennison.com/blog/node/79" target="_blank"&gt;RELAX NG for matching&lt;/a&gt;&amp;quot; &lt;a href="http://www.jenitennison.com/blog/" target="_blank"&gt;Jeni Tennison&lt;/a&gt; said:&lt;/font&gt; 
&lt;p&gt;&lt;font size=2&gt;&lt;/font&gt;  
&lt;blockquote&gt;
&lt;p&gt;&lt;font color="#400080"&gt;The “grouper” is the most interesting and difficult of these. It needs to act like a tokeniser, except use regular expressions over markup rather than over text. For example, say I had:&lt;/font&gt;&lt;pre&gt;&lt;code&gt;&lt;font color="#400080"&gt;&amp;lt;number&amp;gt;06&amp;lt;/number&amp;gt;&amp;lt;punc&amp;gt;/&amp;lt;/punc&amp;gt;&amp;lt;number&amp;gt;03&amp;lt;/number&amp;gt;&amp;lt;punc&amp;gt;/&amp;lt;/punc&amp;gt;&amp;lt;number&amp;gt;08&amp;lt;/number&amp;gt;
&lt;/font&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;font color="#400080"&gt;I want to be able to create a rule that says “any sequence that looks like a number element that contains a &lt;br&gt;two-digit number between 1 and 31, followed by a punc element that contains a slash, followed by another two-digit number between 1 and 12, followed by a punc element that contains a slash, followed by another two-digit number should be wrapped in a date element”.&lt;/font&gt; 
&lt;p&gt;&lt;font color="#400080"&gt;Now this is something that XPath is really bad at. Try writing an expression that selects, from a sequence of elements that may contain other &lt;code&gt;&amp;lt;number&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;punc&amp;gt;&lt;/code&gt; elements as well as other elements, only those sequences of elements that match the pattern I just described. It’s something like:&lt;/font&gt;&lt;pre&gt;&lt;code&gt;&lt;font color="#400080"&gt;number[. &amp;gt;= 1 and . &amp;lt;= 31 and string-length(.) = 2]
      [following-sibling::*[1]/self::punc = '/']
      [following-sibling::*[2]/self::number[. &amp;gt;= 1 and . &amp;lt;= 12 and string-length(.) = 2]]
      [following-sibling::*[3]/self::punc = '/']
      [following-sibling::*[4]/self::number[string-length(.) = 2]]
  /(self::number, following-sibling::*[position() &amp;lt;= 4])
&lt;/font&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;font color="#400080"&gt;which is fiddly and messy and only works in this particular example because I know precisely how many elements there are &lt;br&gt;supposed to be in the group.&lt;/font&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;font size=2&gt;&lt;/font&gt;  
&lt;p&gt;&lt;font size=2&gt;Then she proceeds by making the suggestion that &lt;/font&gt;
&lt;p&gt;&lt;font size=2&gt;    &amp;quot;&lt;font color="#400080"&gt;As a language, RELAX NG is really good at this&lt;/font&gt;&amp;quot;&lt;/font&gt; 
&lt;p&gt;&lt;font size=2&gt;&lt;/font&gt;  
&lt;p&gt;&lt;font size=2&gt;Jeni ends with the following statement:&lt;/font&gt; 
&lt;p&gt;&lt;font size=2&gt;&lt;/font&gt;  
&lt;blockquote&gt;
&lt;p&gt;&lt;font size=2&gt;&amp;quot;&lt;font color="#400080"&gt;So I think a “grouper” component should use RELAX NG to identify sequences to be marked up. But I have no idea if there are RELAX NG libraries out there that can be used in this way: to identify and extract matching sequences rather than to validate entire documents&lt;/font&gt;&amp;quot;&lt;/font&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;font size=2&gt;&lt;/font&gt;  
&lt;p&gt;&lt;font size=2&gt;It is obvious that the solution of this problem is not strictly bound to &lt;a href="http://relaxng.org/"&gt;RELAX NG&lt;/a&gt; itself &lt;br&gt;(which just happens to be able to parse a schema defined using the &lt;a href="http://relaxng.org/compact-20021121.html" target="_blank"&gt;RNC grammar&lt;/a&gt;). The tool Jeni reasons about would be any compiler writing system that allows additional grammar rules, that are not required to reach the start symbol of the language, but may be useful for other purposes.&lt;/font&gt; 
&lt;p&gt;&lt;font size=2&gt;Very fortunately, I know at least one such system: &lt;/font&gt;
&lt;p&gt;&lt;font size=2&gt;         &lt;a href="http://www.cs.chalmers.se/Cs/Research/Language-technology/BNFC/doc/LBNF-report.pdf" target="_blank"&gt;the Labelled BNF Grammar Formalism &lt;/a&gt;(&lt;strong&gt;LBNF&lt;/strong&gt;).&lt;/font&gt; 
&lt;p&gt;&lt;font size=2&gt;&lt;/font&gt; &lt;font size=2&gt;Jeni's &amp;quot;grouper&amp;quot; tool can be implemented by adding additional rules to the language being specified &lt;br&gt;using LBNF's &amp;quot;internal pragmas&amp;quot;.&lt;/font&gt;  
&lt;p&gt;&lt;font size=2&gt;Here's how the authors of LBNF &lt;a href="mailto:markus@cs.chalmers.se" target="_blank"&gt;Markus Forsberg&lt;/a&gt;, &lt;a href="mailto:aarne@cs.chalmers.se" target="_blank"&gt;Aarne Ranta&lt;/a&gt; from &lt;a href="http://www.chalmers.se/cse/EN" target="_blank"&gt;Chalmers University of Technology&lt;/a&gt; &lt;br&gt;and the &lt;a href="http://www.gu.se/" target="_blank"&gt;University of Gothenburg&lt;/a&gt; describe LBNF's internal pragmas:&lt;/font&gt;   
&lt;blockquote&gt;
&lt;p&gt;&lt;font color="#800040" size=2&gt;6 LBNF Pragmas&lt;br&gt;&lt;br&gt;6.1 Internal pragmas&lt;br&gt;&lt;br&gt;Sometimes we want to include in the abstract syntax structures that are not part of the concrete syntax, and hence not parsable. They can be, for instance, syntax trees that are produced by a type-annotating type checker. Even though they are not parsable, we may want to pretty-print them, for instance, in the type checker’s error messages. To define such an internal constructor, we use a pragma &lt;br&gt;&lt;br&gt;    &lt;/font&gt;&lt;font color="#800040" size=2&gt;&amp;quot;internal&amp;quot; Rule &amp;quot;;&amp;quot;&lt;br&gt;&lt;br&gt;where Rule is a normal LBNF rule. For instance,&lt;br&gt;&lt;br&gt;   internal EVarT. Exp ::= &amp;quot;(&amp;quot; Ident &amp;quot;:&amp;quot; Type &amp;quot;)&amp;quot;;&lt;br&gt;&lt;br&gt;introduces a type-annotated variant of a variable expression.&lt;/font&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;font size=2&gt;Of course, LBNF is a very nice and cool tool to carry out a number of really important language development tasks&lt;/font&gt;&lt;font size=2&gt;, &lt;/font&gt;&lt;font size=2&gt;besides the &amp;quot;grouper&amp;quot;.&lt;/font&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=4949635400605856904&amp;page=RSS%3a+Jeni's+%22Grouper%22+(or+how+to+specify+and+parse+additional+rules+to+a+grammar)+is+just+a+minor+task+for+LBNF&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=dnovatchev.spaces.live.com&amp;amp;GT1=dnovatchev"&gt;</description><category>compiler writing systems</category><comments>http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!438.entry#comment</comments><guid isPermaLink="true">http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!438.entry</guid><pubDate>Mon, 17 Mar 2008 04:17:03 GMT</pubDate><slash:comments>1</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://dnovatchev.spaces.live.com/blog/cns!44B0A32C2CCF7488!438/comments/feed.rss</wfw:commentRss><wfw:comment>http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!438.entry#comment</wfw:comment><dcterms:modified>2008-03-17T04:50:45Z</dcterms:modified></item><item><title>Wide Finder in XSLT --&gt; deriving new requirements for efficiency in XSLT processors.</title><link>http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!385.entry</link><description>&lt;p&gt;With his twelve posts under the common title of &amp;quot;&lt;a href="http://www.tbray.org/ongoing/When/200x/2007/09/20/Wide-Finder" target="_blank"&gt;&lt;strong&gt;The Wide Finder Project&lt;/strong&gt;&lt;/a&gt;&amp;quot; &lt;a href="http://www.tbray.org/ongoing" target="_blank"&gt;&lt;strong&gt;Tim Bray&lt;/strong&gt;&lt;/a&gt; formulated a &lt;a href="http://www.oreilly.com/catalog/9780596510046/" target="_blank"&gt;&lt;strong&gt;problem&lt;/strong&gt;&lt;/a&gt;, which obviously has since then stirred some people, anxious to prove that their programming language of choice fares well in implementing solutions for this class of problems. 
&lt;p&gt;While I am not aware of any XSLT implementation that provides explicit or implicit support for parallel processing (with the obvious goal to take advantage of the multi-core processors that have almost reached a &amp;quot;prevalent&amp;quot; status today), I was curious to determine at least two things: 
&lt;ul&gt;
&lt;li&gt;How well a good XSLT 2.0 processor and a straightforward solution fare against other languages/solutions? 
&lt;li&gt;Where is the XSLT code on the scale of &amp;quot;beautiful code&amp;quot;? &lt;/ul&gt;
&lt;p&gt;  
&lt;p&gt;Before going further let me remind that there is a popular (and as we'll see unfounded!) belief that any XSLT solution must be hugely inefficient and that any XSLT code can only be ugly. In fact, the &lt;a href="http://www.tbray.org/ongoing/When/200x/2007/09/21/Erlang#c1190734319.576466" target="_blank"&gt;following comment&lt;/a&gt; to one of Tim's posts reflects exactly this mindset: 
&lt;p&gt;  
&lt;table style="background:#eeece1" cellspacing=0 cellpadding=2 width=400 border=0&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td valign=top width=400&gt;
&lt;p&gt;&amp;quot;&lt;font style="background-color:#eeece1"&gt;From: Rornan (Sep 25 2007, at 08:31)&lt;/font&gt; 
&lt;p&gt;&lt;font style="background-color:#eeece1"&gt;Tim,&lt;/font&gt; 
&lt;p&gt;&lt;font style="background-color:#eeece1"&gt;If you had anything at all to do with creating XSLT, then you have no right at all to comment on any other language deficency ever ever again.&amp;quot;&lt;/font&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;   
&lt;p&gt;My initial XSLT solution to Tim's problem is below. No optimization attempts have been attempted, not only because I don't have an XSLT processor that utilizes multi-core processor, but also because it seems there's only a limited possibility for optimization (adding more CPU's is not likely to speed up the reading of a huge file from a single drive). 
&lt;p&gt;  &lt;pre style="font-size:10pt;color:#000000;font-family:courier new;background-color:#c6f0f2"&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-weight:bold;color:#800080;background-color:#c6f0f2"&gt;xsl:stylesheet&lt;/span&gt; &lt;span style="color:#800080;background-color:#c6f0f2"&gt;version&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#c6f0f2"&gt;2.0&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;background-color:#c6f0f2"&gt;xmlns:xsl&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#ff0000;background-color:#c6f0f2"&gt;&lt;a href="http://www.w3.org/1999/XSL/Transform&amp;quot;"&gt;http://www.w3.org/1999/XSL/Transform&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;quot;
&lt;/span&gt;&lt;/a&gt; &lt;span style="color:#ff0000;background-color:#c6f0f2"&gt;xmlns:xs&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#ff0000;background-color:#c6f0f2"&gt;http://www.w3.org/2001/XMLSchema&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;quot;&amp;gt;
&lt;/span&gt;  &lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-weight:bold;color:#800080;background-color:#c6f0f2"&gt;xsl:output&lt;/span&gt; &lt;span style="color:#800080;background-color:#c6f0f2"&gt;method&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#c6f0f2"&gt;text&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;quot;/&amp;gt;&lt;br&gt;
&lt;/span&gt; &lt;span style="color:#0000ff;background-color:#c6f0f2"&gt; &amp;lt;&lt;/span&gt;&lt;span style="font-weight:bold;color:#800080;background-color:#c6f0f2"&gt;xsl:variable&lt;/span&gt; &lt;span style="color:#800080;background-color:#c6f0f2"&gt;name&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#c6f0f2"&gt;vLines&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:#c6f0f2;background-color:#ff0000"&gt;as&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#c6f0f2"&gt;xs:string*&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:#800080;background-color:#c6f0f2"&gt;select&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;=
   &amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#c6f0f2"&gt;tokenize(unparsed-text('file:///C:/Log1000000.txt'),'\n')&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;quot;/&amp;gt;&lt;br&gt;
&lt;/span&gt;  &lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-weight:bold;color:#800080;background-color:#c6f0f2"&gt;xsl:variable&lt;/span&gt; &lt;span style="color:#800080;background-color:#c6f0f2"&gt;name&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#c6f0f2"&gt;vRegEx&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:#c6f0f2;background-color:#ff0000"&gt;as&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#c6f0f2"&gt;xs:string&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:#800080;background-color:#c6f0f2"&gt;select&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;=
&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#c6f0f2"&gt;'^.*?GET /ongoing/When/[0-9]{3}x/([0-9]{4}/[0-9]{2}/[0-9]{2}/[^ .]+) .*$|^.+$'&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;quot;/&amp;gt;&lt;br&gt;
&lt;/span&gt;  &lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-weight:bold;color:#800080;background-color:#c6f0f2"&gt;xsl:template&lt;/span&gt; &lt;span style="color:#800080;background-color:#c6f0f2"&gt;match&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#c6f0f2"&gt;/&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;quot;&amp;gt;
&lt;/span&gt; &lt;span style="background-color:#c6f0f2"&gt;  &lt;/span&gt; &lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#c6f0f2"&gt;xsl:for-each-group group-by&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#c6f0f2"&gt;.&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:#800000;background-color:#c6f0f2"&gt;select&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;=
    &amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#c6f0f2"&gt;for $line in $vLines
         return replace($line,$vRegEx,'$1')[.]&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;quot;&amp;gt;
&lt;/span&gt; &lt;span style="background-color:#c6f0f2"&gt;    &lt;/span&gt; &lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-weight:bold;color:#800080;background-color:#c6f0f2"&gt;xsl:sort&lt;/span&gt; &lt;span style="color:#800080;background-color:#c6f0f2"&gt;select&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#c6f0f2"&gt;count(current-group())&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:#800080;background-color:#c6f0f2"&gt;order&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#c6f0f2"&gt;descending&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;quot; /&amp;gt;&lt;br&gt;
&lt;/span&gt; &lt;span style="background-color:#c6f0f2"&gt;    &lt;/span&gt; &lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-weight:bold;color:#800080;background-color:#c6f0f2"&gt;xsl:if&lt;/span&gt; &lt;span style="color:#800080;background-color:#c6f0f2"&gt;test&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#c6f0f2"&gt;not(position() &amp;gt; 10)&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;quot;&amp;gt;
&lt;/span&gt;&lt;span style="background-color:#c6f0f2"&gt;  &lt;/span&gt;     &lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-weight:bold;color:#800080;background-color:#c6f0f2"&gt;xsl:value-of&lt;/span&gt; &lt;span style="color:#800080;background-color:#c6f0f2"&gt;select&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;=&lt;br&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight:bold;color:#ff0000;background-color:#c6f0f2"&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;quot;concat(count(current-group()),':',current-grouping-key(),'&amp;amp;#xA;')&amp;quot;/&amp;gt;
&lt;/span&gt; &lt;span style="background-color:#c6f0f2"&gt;    &lt;/span&gt; &lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-weight:bold;color:#800080;background-color:#c6f0f2"&gt;xsl:if&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;gt;
&lt;/span&gt; &lt;span style="background-color:#c6f0f2"&gt;  &lt;/span&gt; &lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;background-color:#c6f0f2"&gt;xsl:for-each-group&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;gt;
&lt;/span&gt;  &lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-weight:bold;color:#800080;background-color:#c6f0f2"&gt;xsl:template&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="font-weight:bold;color:#800080;background-color:#c6f0f2"&gt;xsl:stylesheet&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;This 22-line-transformation is performed by Saxon 9.0 on a 3GHz DELL desktop. The file Log1000000.txt was constructed using the 10000 lines file provided by Tim and copying it into another file 100 times. The size of this file is about 200MB. 
&lt;p&gt;&lt;strong&gt;The results were produced in 36.175 seconds using about 929MB of RAM&lt;/strong&gt;. Saxon should be timed using the -repeat:3 command-line option, which performs the transformation three times. Using only the results from the first/single transformation will be misleading, as they include the time for the Java VM startup. 
&lt;p&gt;  
&lt;h2&gt;Discussion&lt;/h2&gt;
&lt;p&gt;  
&lt;h3&gt;To answer the questions:&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;1. How well a good XSLT 2.0 processor and a straightforward solution fare against other languages/solutions?&lt;/em&gt; 
&lt;p&gt;The non-optimized, uniprocessor version of this solution has a time of 36 seconds for processing about 200MB log file. It is likely the timing for the full , five times bigger log file used by Tim Bray, will be about 5 times bigger: 180 sec, or about 3 minutes. 3 minutes for processing 1GB of data is not a bad time for an XSLT transformation, considering that sizes even of a few hundreds of megs are still considered monstrous. 
&lt;p&gt;XSLT could be in fact one of the winners in the WF competition, had its creators stepped just a little bit further exploiting the natural, non-sequential XSLT processing model. Here I am talking about specifying a single f:parMap() function, which can be defined exactly as the current FXSL f:map() function: &lt;pre style="font-size:10pt;color:#000000;font-family:courier new;background-color:#c6f0f2"&gt;&lt;span style="font-weight:bold;background-color:#c6f0f2"&gt;  &lt;/span&gt; &lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#c6f0f2"&gt;xsl:function name&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#c6f0f2"&gt;f:map&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:#800000;background-color:#c6f0f2"&gt;as&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#c6f0f2"&gt;item()*&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;quot;&amp;gt;
&lt;/span&gt; &lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;     &amp;lt;&lt;/span&gt;&lt;span style="font-weight:bold;color:#800080;background-color:#c6f0f2"&gt;xsl:param&lt;/span&gt; &lt;span style="color:#800080;background-color:#c6f0f2"&gt;name&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#c6f0f2"&gt;pFun&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:#c6f0f2;background-color:#ff0000"&gt;as&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#c6f0f2"&gt;element()&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;quot;/&amp;gt;
&lt;/span&gt; &lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;     &amp;lt;&lt;/span&gt;&lt;span style="font-weight:bold;color:#800080;background-color:#c6f0f2"&gt;xsl:param&lt;/span&gt; &lt;span style="color:#800080;background-color:#c6f0f2"&gt;name&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#c6f0f2"&gt;pList1&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:#c6f0f2;background-color:#ff0000"&gt;as&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#c6f0f2"&gt;item()*&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;quot;/&amp;gt;

&lt;/span&gt; &lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;     &amp;lt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#c6f0f2"&gt;xsl:sequence select&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;=
       &amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#c6f0f2"&gt;for $this in $pList1 return
          f:apply($pFun, $this)&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;quot;
      /&amp;gt;
&lt;/span&gt; &lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;   &amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;background-color:#c6f0f2"&gt;xsl:function&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#c6f0f2"&gt;&amp;gt;

&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;  
&lt;p&gt;The only difference is that f:parMap() adds to the semantics of f:map() the hint to use as many available CPU processors as appropriate when evaluating the &amp;quot;for&amp;quot; expression in the code of the function. 
&lt;p&gt;Yes, this can be done for any &amp;quot;/&amp;quot; operator or for any &amp;quot;for&amp;quot; expression such as the one used in lines 13 - 14 in our XSLT solution: 
&lt;p&gt;&amp;quot;for $line in $vLines&lt;br&gt;     return replace($line,$vRegEx,'$1')[.]&amp;quot; 
&lt;p&gt;  
&lt;p&gt;and for any &amp;lt;xsl:apply-templates .../&amp;gt; instruction, and for any &amp;lt;xsl:for-each .../&amp;gt; instruction, and for any &amp;lt;xsl:for-each-group ...&amp;gt; instruction and ... and ... and ... 
&lt;p&gt;  
&lt;p&gt;Judging from the &lt;a href="http://www.tbray.org/ongoing/When/200x/2007/10/30/WF-Results" target="_blank"&gt;&lt;strong&gt;published results&lt;/strong&gt;&lt;/a&gt;, this straightforward, non-optimized uniprocessor XSLT solution comes not too-far behind some of the optimized for multi-processing solutions. I hope that in the not so distant future there will be XSLT processors exploiting the inherent non-sequential nature of XSLT processing to implement highly-optimized multi-processing solutions. 
&lt;p&gt;2. &lt;em&gt;Where is the XSLT code on the scale of &amp;quot;beautiful code&amp;quot;?&lt;/em&gt; 
&lt;p&gt;By its compactness (22 lines) it is in 3rd place and rivals the 2nd place (17 lines), as we could easily remove 4 lines (3 of them blank) used to add readability. One of Tim's criteria for &amp;quot;beautiful code&amp;quot; is avoiding awkwardness.He speaks about Ruby not needing ending semicolons or variable type declarations. However, Tim's solution still had to use two lines for defining a hash and setting its default to 0. By contrast, the XSLT solution above does not require the programmer to introduce and initialize a special data structure -- the support for grouping is right there in the core of the language. There is simply no way the programmer can do something wrong in declaring or using a hash table. 
&lt;p&gt;  
&lt;h3&gt;What could the XSLT processor do better?&lt;/h3&gt;
&lt;p&gt;Both the timing and especially the amount of RAM used indicate how the XSLT processor did its work: 
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;It read all the text file in memory. 
&lt;li&gt;Then it produced all $vLines strings. 
&lt;li&gt;Then it produced the line replacements. 
&lt;li&gt;Then it did the grouping/sorting on the line replacements. &lt;/ul&gt;&lt;/div&gt;
&lt;p&gt;Imagine that the XSLT Processor is really lazy: 
&lt;ul&gt;
&lt;li&gt;It will not read any contents of the file and will not do any tokenization, until absolutely necessary. 
&lt;li&gt;Whenever it is really necessary to use the next token (line), only the text necessary to determine that line shall be read. 
&lt;li&gt;Whenever a token/line is produced, all previously used / unused text shall be marked-for-garbage-collection/discarded/reused. 
&lt;li&gt;Whenever a string from $vLines is consumed and processed by the &amp;lt;xsl:for-each-group .../&amp;gt; instruction, this string is no-longer used and shall be marked-for-garbage-collection/discarded/reused. &lt;/ul&gt;
&lt;p&gt;Using these rules a truly lazy XSLT processor will only need space large enough for the longest line, and for a hash table to keep the keys and counters for all different articles being grouped. In this case there are just 562 unique values extracted from the strings of $vLines. 
&lt;p&gt;In this way, the processing -- reading a line, finding the article it contains and feeding this to the hash table --  could be accomplished in streaming mode while reading the text file. Upon reaching the end of the file, there would be very little left to do, and thus almost nothing to be further optimized. 
&lt;p&gt;  
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;I truly believe that the described improvements can be implemented by at least some of the best XSLT 2.0 processors around here. For many years I have been using Saxon and am very grateful to its developer Dr. Michael Kay. The performance efficiency has been constantly growing -- a very good example to follow by all other XSLT vendors and if they do there will be competition, and competition is good for us all.&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=4949635400605856904&amp;page=RSS%3a+Wide+Finder+in+XSLT+--%3e+deriving+new+requirements+for+efficiency+in+XSLT+processors.&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=dnovatchev.spaces.live.com&amp;amp;GT1=dnovatchev"&gt;</description><category>XSLT 2.0</category><comments>http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!385.entry#comment</comments><guid isPermaLink="true">http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!385.entry</guid><pubDate>Fri, 09 Nov 2007 19:40:25 GMT</pubDate><slash:comments>5</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://dnovatchev.spaces.live.com/blog/cns!44B0A32C2CCF7488!385/comments/feed.rss</wfw:commentRss><wfw:comment>http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!385.entry#comment</wfw:comment><dcterms:modified>2007-11-09T19:54:01Z</dcterms:modified></item><item><title>Closure in XSLT</title><link>http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!384.entry</link><description>&lt;p&gt;In a recent post to the xml-dev mailing list, &amp;quot;&lt;a href="http://lists.xml.org/archives/xml-dev/200710/msg00270.html" target="_blank"&gt;&lt;strong&gt;XSLT question on transitive closures&lt;/strong&gt;&lt;/a&gt;&amp;quot;, &lt;a href="http://www.oreillynet.com/pub/au/1712" target="_blank"&gt;&lt;strong&gt;Rick Jelliffe&lt;/strong&gt;&lt;/a&gt; wrote: 
&lt;p&gt;  
&lt;p&gt;&amp;quot;&lt;font color="#800000"&gt;Am I right in thinking that&lt;/font&gt; 
&lt;p&gt;&lt;font color="#800000"&gt; 1) XPath2 functions don't have have a function for transitive closure (along provided xpaths) &lt;/font&gt;
&lt;p&gt;&lt;font color="#800000"&gt;2) SAXON 8 does not have the saxon:closure() extension function that older versions of SAXON had &lt;/font&gt;
&lt;p&gt;&lt;font color="#800000"&gt;3) The one to use is probably still Christian Nentwich's code from circa 2001 as adopted into EXSLT&lt;/font&gt; ?&amp;quot; 
&lt;p&gt;  
&lt;p&gt;&lt;a href="http://saxonica.blogharbor.com/blog" target="_blank"&gt;&lt;strong&gt;Michael Kay&lt;/strong&gt;&lt;/a&gt; &lt;a href="http://lists.xml.org/archives/xml-dev/200710/msg00271.html" target="_blank"&gt;&lt;strong&gt;replied&lt;/strong&gt;&lt;/a&gt;: 
&lt;p&gt;&amp;quot;&lt;font color="#800000"&gt;I think it would be nice to do it properly based on FXSL higher-order functions, which are much more cleanly specified. Perhaps there is already a suitable function in FXSL. &lt;/font&gt;
&lt;p&gt;&lt;font color="#800000"&gt;The other thing that's needed is the ability to check for cycles. Simply blowing the stack or looping isn't good enough&lt;/font&gt;.&amp;quot; 
&lt;p&gt;  
&lt;p&gt;&lt;a href="http://dpcarlisle.blogspot.com/feeds/posts/default" target="_blank"&gt;&lt;strong&gt;David Carlisle&lt;/strong&gt;&lt;/a&gt; replied by providing a &lt;a href="http://lists.xml.org/archives/xml-dev/200710/msg00272.html" target="_blank"&gt;&lt;strong&gt;solution&lt;/strong&gt;&lt;/a&gt; that would dynamically generate a new XSLT stylesheet and a closure function in it that uses only a specific function and implements its closure. He also said: 
&lt;p&gt;  
&lt;p&gt;&amp;quot;&lt;font color="#800000"&gt;&amp;gt; I think it would be nice to do it properly based on FXSL higher-order &lt;/font&gt;
&lt;p&gt;&lt;font color="#800000"&gt;True (but I'll leave that for Dimitre  :-)&lt;/font&gt;&amp;quot; 
&lt;p&gt;  
&lt;p&gt;Thanks to these nice people I felt just like... something had been left for me  :o) 
&lt;p&gt;So, now we have in FXSL the function 
&lt;p&gt;   &lt;a href="http://fxsl.cvs.sourceforge.net/fxsl/fxsl-xslt2/f/func-closure.xsl?revision=1.1&amp;amp;view=markup&amp;amp;sortby=date" target="_blank"&gt;&lt;strong&gt;f:closure()&lt;/strong&gt;&lt;/a&gt; 
&lt;p&gt;which, given a function pFun and a starting set of items pstartSet, produces the transitive closure of pFun. 
&lt;p&gt;  
&lt;p&gt;While the complete 47 lines of code can be viewed using the above link, the essence of the implementation is in the following 20 lines: 
&lt;p&gt; &lt;pre style="font-size:10pt;color:#000000;font-family:courier new;background-color:#ccf2f9"&gt; &lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#ccf2f9"&gt;xsl:function name&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#ccf2f9"&gt;f:closure&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:#800000;background-color:#ccf2f9"&gt;as&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#ccf2f9"&gt;node()*&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;quot;&amp;gt;
&lt;/span&gt; &lt;span style="background-color:#ccf2f9"&gt;  &lt;/span&gt; &lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-weight:bold;color:#800080;background-color:#ccf2f9"&gt;xsl:param&lt;/span&gt; &lt;span style="color:#800080;background-color:#ccf2f9"&gt;name&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#ccf2f9"&gt;pFun&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:#ccf2f9;background-color:#ff0000"&gt;as&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#ccf2f9"&gt;element()&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;quot;/&amp;gt;
&lt;/span&gt; &lt;span style="background-color:#ccf2f9"&gt;  &lt;/span&gt; &lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-weight:bold;color:#800080;background-color:#ccf2f9"&gt;xsl:param&lt;/span&gt; &lt;span style="color:#800080;background-color:#ccf2f9"&gt;name&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#ccf2f9"&gt;pstartSet&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:#ccf2f9;background-color:#ff0000"&gt;as&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#ccf2f9"&gt;node()*&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;quot;/&amp;gt;
&lt;/span&gt; &lt;span style="background-color:#ccf2f9"&gt;   
   &lt;/span&gt; &lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#ccf2f9"&gt;xsl:sequence select&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#ccf2f9"&gt;f:closure2($pFun, $pstartSet,$pstartSet)&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;quot;/&amp;gt;
&lt;/span&gt;  &lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;background-color:#ccf2f9"&gt;xsl:function&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;gt;
&lt;/span&gt; &lt;span style="background-color:#ccf2f9"&gt; 
 &lt;/span&gt; &lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#ccf2f9"&gt;xsl:function name&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#ccf2f9"&gt;f:closure2&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:#800000;background-color:#ccf2f9"&gt;as&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#ccf2f9"&gt;node()*&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;quot;&amp;gt;
&lt;/span&gt; &lt;span style="background-color:#ccf2f9"&gt;  &lt;/span&gt; &lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-weight:bold;color:#800080;background-color:#ccf2f9"&gt;xsl:param&lt;/span&gt; &lt;span style="color:#800080;background-color:#ccf2f9"&gt;name&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#ccf2f9"&gt;pFun&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:#ccf2f9;background-color:#ff0000"&gt;as&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#ccf2f9"&gt;element()&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;quot;/&amp;gt;
&lt;/span&gt; &lt;span style="background-color:#ccf2f9"&gt;  &lt;/span&gt; &lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-weight:bold;color:#800080;background-color:#ccf2f9"&gt;xsl:param&lt;/span&gt; &lt;span style="color:#800080;background-color:#ccf2f9"&gt;name&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#ccf2f9"&gt;pCurClosure&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:#ccf2f9;background-color:#ff0000"&gt;as&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#ccf2f9"&gt;node()*&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;quot;/&amp;gt;
&lt;/span&gt; &lt;span style="background-color:#ccf2f9"&gt;  &lt;/span&gt; &lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-weight:bold;color:#800080;background-color:#ccf2f9"&gt;xsl:param&lt;/span&gt; &lt;span style="color:#800080;background-color:#ccf2f9"&gt;name&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#ccf2f9"&gt;pstartSet&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:#ccf2f9;background-color:#ff0000"&gt;as&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#ccf2f9"&gt;node()*&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;quot;/&amp;gt;
&lt;/span&gt; &lt;span style="background-color:#ccf2f9"&gt;   
   &lt;/span&gt; &lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-weight:bold;color:#800080;background-color:#ccf2f9"&gt;xsl:if&lt;/span&gt; &lt;span style="color:#800080;background-color:#ccf2f9"&gt;test&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#ccf2f9"&gt;exists($pstartSet)&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;quot;&amp;gt;
&lt;/span&gt; &lt;span style="background-color:#ccf2f9"&gt;    &lt;/span&gt; &lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-weight:bold;color:#800080;background-color:#ccf2f9"&gt;xsl:variable&lt;/span&gt; &lt;span style="color:#800080;background-color:#ccf2f9"&gt;name&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="font-weight:bold;color:#000000;background-color:#ccf2f9"&gt;vNew&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:#800080;background-color:#ccf2f9"&gt;select&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;=
&lt;/span&gt; &lt;span style="background-color:#ccf2f9"&gt;        &lt;/span&gt; &lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;quot;f:map($pFun,$pstartSet) except $pCurClosure&amp;quot;/&amp;gt;
&lt;/span&gt; &lt;span style="background-color:#ccf2f9"&gt;    &lt;/span&gt; &lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#ccf2f9"&gt;xsl:sequence select&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;=
&lt;/span&gt; &lt;span style="background-color:#ccf2f9"&gt;         &lt;/span&gt; &lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;quot;$pstartSet 
&lt;/span&gt; &lt;span style="background-color:#ccf2f9"&gt;         &lt;/span&gt; &lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;| $vNew 
&lt;/span&gt; &lt;span style="background-color:#ccf2f9"&gt;         &lt;/span&gt; &lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;| f:closure2($pFun,$pCurClosure | $vNew, $vNew)&amp;quot;/&amp;gt;
&lt;/span&gt; &lt;span style="background-color:#ccf2f9"&gt;  &lt;/span&gt; &lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-weight:bold;color:#800080;background-color:#ccf2f9"&gt;xsl:if&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;gt;
&lt;/span&gt;  &lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;background-color:#ccf2f9"&gt;xsl:function&lt;/span&gt;&lt;span style="color:#0000ff;background-color:#ccf2f9"&gt;&amp;gt;
&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;   
&lt;p&gt;And here is my reply to David's post (code hyperlinked, full code omitted): 
&lt;p&gt;&amp;quot;&lt;br&gt;&amp;gt;&amp;gt; I think it would be nice to do it properly based on FXSL higher-order 
&lt;p&gt;&amp;gt; &amp;gt; True (but I'll leave that for Dimitre:-) 
&lt;p&gt;I am sorry I only read this a few days ago. Below is the code of the FXSL function. While the code is straightforward, the following must be noted: 
&lt;p&gt;1. The &amp;quot;set&amp;quot; at present is only a set of nodes. I will probably produce a more general f:closure() function, which operates on any set of items. Then this function should be also passed as parameters a &amp;quot;union&amp;quot; and a &amp;quot;difference&amp;quot; functions. 
&lt;p&gt;2. It seems that David's solution would go into an infinite loop for more involved examples (see the second test with reachability of nodes in cyclic graphs below). Therefore, the algorithm was slightly changed and works correctly. The following files can be downloaded from the CVS of the FXSL project: 
&lt;p&gt;&lt;a href="http://fxsl.cvs.sourceforge.net/fxsl/fxsl-xslt2/f/func-closure.xsl?revision=1.1&amp;amp;view=markup&amp;amp;sortby=date" target="_blank"&gt;&lt;strong&gt;func-closure.xsl&lt;/strong&gt;&lt;/a&gt;. 
&lt;p&gt;&lt;a href="http://fxsl.cvs.sourceforge.net/fxsl/fxsl-xslt2/Tests/testFunc-closure.xsl?revision=1.1&amp;amp;view=markup&amp;amp;sortby=date" target="_blank"&gt;&lt;strong&gt;testFunc-closure.xsl&lt;/strong&gt;&lt;/a&gt;, 
&lt;p&gt;&lt;a href="http://fxsl.cvs.sourceforge.net/fxsl/fxsl-xslt2/Tests/testFunc-closure2.xsl?revision=1.1&amp;amp;view=markup&amp;amp;sortby=date" target="_blank"&gt;&lt;strong&gt;testFunc-closure2.xsl&lt;/strong&gt;&lt;/a&gt; 
&lt;p&gt;The last transformation should be applied on the following xml file: &lt;br&gt;&lt;a href="http://fxsl.cvs.sourceforge.net/fxsl/fxsl-xslt2/data/testFunc-closure2.xml?revision=1.1&amp;amp;view=markup&amp;amp;sortby=date" target="_blank"&gt;&lt;strong&gt;testFunc-closure2.xml&lt;/strong&gt;&lt;/a&gt; 
&lt;p&gt;  
&lt;p&gt;The result from running the second test transformation above (two cases of finding all nodes of a given graph, reachable from a specific node. In the second case there is a cycle involving the nodes V2, V6, V7) is: 
&lt;p&gt; === Reachable from V1 ======= 
&lt;p&gt;&amp;lt;node id=&amp;quot;V1&amp;quot;/&amp;gt; &lt;br&gt;&amp;lt;node id=&amp;quot;V3&amp;quot;/&amp;gt;&lt;br&gt;&amp;lt;node id=&amp;quot;V4&amp;quot;/&amp;gt; &lt;br&gt;&amp;lt;node id=&amp;quot;V5&amp;quot;/&amp;gt; &lt;br&gt;======================= 
&lt;p&gt;&lt;br&gt;=== Reachable from V2 ======= &lt;br&gt;&amp;lt;node id=&amp;quot;V2&amp;quot;/&amp;gt; &lt;br&gt;&amp;lt;node id=&amp;quot;V4&amp;quot;/&amp;gt; &lt;br&gt;&amp;lt;node id=&amp;quot;V5&amp;quot;/&amp;gt; &lt;br&gt;&amp;lt;node id=&amp;quot;V6&amp;quot;/&amp;gt; &lt;br&gt;&amp;lt;node id=&amp;quot;V7&amp;quot;/&amp;gt; &lt;br&gt;======================= 
&lt;p&gt;  
&lt;p&gt;Due to its generality, the f:closure() function is a useful addition to the FXSL library. &lt;br&gt;
&lt;p&gt;Cheers, Dimitre Novatchev&lt;br&gt;&amp;quot; 
&lt;p&gt; &lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=4949635400605856904&amp;page=RSS%3a+Closure+in+XSLT&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=dnovatchev.spaces.live.com&amp;amp;GT1=dnovatchev"&gt;</description><comments>http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!384.entry#comment</comments><guid isPermaLink="true">http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!384.entry</guid><pubDate>Sun, 04 Nov 2007 16:48:04 GMT</pubDate><slash:comments>3</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://dnovatchev.spaces.live.com/blog/cns!44B0A32C2CCF7488!384/comments/feed.rss</wfw:commentRss><wfw:comment>http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!384.entry#comment</wfw:comment><dcterms:modified>2007-11-05T14:11:16Z</dcterms:modified></item><item><title>Kurt Cagle: Bridging XML E4X and JSON</title><link>http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!374.entry</link><description>&lt;p&gt;Using this title &lt;a href="http://www.xforms.org/metaweb/?q=node/31" target="_blank"&gt;Kurt Cagle writes&lt;/a&gt;: 
&lt;p&gt;&amp;quot;I'd like to push a proposal to both the XML and AJAX communities, something that I think needs to be taken up by the W3C, the OpenAJAX alliance and JSON.org especially. Establish a set of conventions within JSON that most readily facilitate JSON being used in an XML context. These conventions should be syntactical, things that can be done with hash key naming conventions that can be picked up by a JSON/XML bridge to transform between the two formats.&amp;quot; 
&lt;p&gt;  
&lt;p&gt;Hmm...  here's what I have to say: 
&lt;p&gt;Kurt, this was quietly done some time ago. Just have a look at my blog (&amp;quot;&lt;a href="http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!367.entry" target="_blank"&gt;Transforming JSON&lt;/a&gt;&amp;quot;). &lt;a href="http://www.oreillynet.com/pub/au/2354" target="_blank"&gt;M.David. Peterson&lt;/a&gt; has a &lt;a href="http://dev.amp.fm/service/json-to-xml/?debug=true&amp;amp;uri=http://api.local.yahoo.com/MapsService/V1/trafficData?appid=EricBlogDemo&amp;amp;amp;city=Seattle&amp;amp;amp;state=wa&amp;amp;amp;output=json" target="_blank"&gt;nice web-service based example&lt;/a&gt;, which in real time gets the XML out of the JSON produced by the &lt;a href="http://api.local.yahoo.com/MapsService/V1/trafficData?appid=EricBlogDemo&amp;amp;city=Seattle&amp;amp;state=wa&amp;amp;output=json" target="_blank"&gt;Yahoo's Traffic Service&lt;/a&gt;. 
&lt;p&gt;This example just uses the JSON to XML convertor provided by FXSL -- that is the function &lt;a href="http://fxsl.cvs.sourceforge.net/fxsl/fxsl-xslt2/f/func-json-document.xsl?revision=1.9&amp;amp;view=markup&amp;amp;sortby=date"&gt;f:json-document()&lt;/a&gt;, written in pure XSLT. 
&lt;p&gt;So, no conventions are necessary for transforming JSON to XML !&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=4949635400605856904&amp;page=RSS%3a+Kurt+Cagle%3a+Bridging+XML+E4X+and+JSON&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=dnovatchev.spaces.live.com&amp;amp;GT1=dnovatchev"&gt;</description><comments>http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!374.entry#comment</comments><guid isPermaLink="true">http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!374.entry</guid><pubDate>Sat, 13 Oct 2007 18:08:44 GMT</pubDate><slash:comments>7</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://dnovatchev.spaces.live.com/blog/cns!44B0A32C2CCF7488!374/comments/feed.rss</wfw:commentRss><wfw:comment>http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!374.entry#comment</wfw:comment><dcterms:modified>2007-10-13T18:14:23Z</dcterms:modified></item><item><title>Transforming JSON</title><link>http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!367.entry</link><description>&lt;div&gt;
&lt;p&gt;&lt;font style="background-color:#ffff00"&gt;Update: (&lt;strong&gt;Think that&lt;/strong&gt;) finally managed to get from Windows Live Spaces the formatting I wanted... &lt;/font&gt;
&lt;p&gt;Update: Enhanced the JSON Lexer to properly deal with escaped characters within strings. How to handle \b and \f ???   
&lt;p&gt;==================================== 
&lt;p&gt;Ever wanted to access and manipulate &lt;strong&gt;&lt;a href="http://json.org/"&gt;JSON&lt;/a&gt;&lt;/strong&gt; as ordinary XML? &lt;span&gt;To transform it with XSLT?&lt;/span&gt; 
&lt;p&gt;No problem, use the &lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;&lt;a href="http://fxsl.cvs.sourceforge.net/fxsl/fxsl-xslt2/f/func-json-document.xsl?view=markup&amp;amp;sortby=date"&gt;&lt;span&gt;f&lt;span&gt;:json&lt;/span&gt;&lt;/span&gt;-document()&lt;/a&gt; &lt;/span&gt;&lt;/strong&gt;and &lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;&lt;a href="http://fxsl.cvs.sourceforge.net/fxsl/fxsl-xslt2/f/func-json-document.xsl?view=markup&amp;amp;sortby=date"&gt;&lt;span&gt;f:json&lt;/span&gt;-file-document()&lt;/a&gt; &lt;/span&gt;&lt;/strong&gt;as provided by &lt;strong&gt;&lt;a href="http://fxsl.sf.net/"&gt;FXSL&lt;/a&gt;&lt;/strong&gt;. 
&lt;p&gt;Here is &lt;strong&gt;&lt;a href="http://fxsl.cvs.sourceforge.net/fxsl/fxsl-xslt2/Tests/testFunc-json-document2.xsl?view=markup&amp;amp;sortby=date"&gt;a quick example&lt;/a&gt;&lt;/strong&gt;: 
&lt;p&gt;Let's have (yes, this is the &lt;a href="http://api.local.yahoo.com/MapsService/V1/trafficData?appid=EricBlogDemo&amp;amp;city=Seattle&amp;amp;state=wa&amp;amp;output=json"&gt;Yahoo Traffic Service&lt;/a&gt;): 
&lt;p&gt;  
&lt;table cellspacing=0 cellpadding=2 width=800 border=0&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td valign=top width=798&gt;
&lt;table style="border-right:medium none;border-top:medium none;background:#d2fafe;border-left:medium none;border-bottom:medium none;border-collapse:collapse" cellspacing=0 cellpadding=0 border=1&gt;
&lt;tbody&gt;
&lt;tr style=""&gt;
&lt;td valign=top width=798&gt;
&lt;p style="line-height:normal"&gt; 
&lt;table style="background:#daeef3;border-collapse:collapse" cellspacing=0 cellpadding=0 border=0&gt;
&lt;tbody&gt;
&lt;tr style=""&gt;
&lt;td valign=top width=798&gt;
&lt;p style="line-height:normal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;xsl:variable &lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;name&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;vStr&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt; {&amp;quot;ResultSet&amp;quot;:  &lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;   {&amp;quot;LastUpdateDate&amp;quot;:&amp;quot;1178683597&amp;quot;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;    &amp;quot;Result&amp;quot;:[{&amp;quot;type&amp;quot;:&amp;quot;construction&amp;quot;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;               &amp;quot;Title&amp;quot;:&amp;quot;Construction work, on I-5 NB at SENECA ST&amp;quot;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;               &amp;quot;Description&amp;quot;:&amp;quot;I 5 N Construction work, Left Lane Blocked on I 5 northbound from Seneca Street to Pine Street starting 11:00 PM, 05 08 07 for several days from 11:00pm to 05:00am on Tuesdays, Wednesdays and Thursdays . From milepost 165 to milepost 167&amp;quot;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;               &amp;quot;Latitude&amp;quot;:&amp;quot;47.614353&amp;quot;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;               &amp;quot;Longitude&amp;quot;:&amp;quot;-122.329586&amp;quot;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;               &amp;quot;Direction&amp;quot;:&amp;quot;NB&amp;quot;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;               &amp;quot;Severity&amp;quot; :  2,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;               &amp;quot;ReportDate&amp;quot;:1178604000,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;               &amp;quot;UpdateDate&amp;quot;:1178608792,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;               &amp;quot;EndDate&amp;quot;:1178712000},&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt; &lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;              {&amp;quot;type&amp;quot;:&amp;quot;construction&amp;quot;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;               &amp;quot;Title&amp;quot;:&amp;quot;Construction work, on I-5 NB at UNIVERSITY ST&amp;quot;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;               &amp;quot;Description&amp;quot;:&amp;quot;I 5 N Construction work, On ramp Blocked on I 5 northbound at University Street starting 10:00 PM, 05 08 07 until further notice from 10:00pm to 05:00am on Tuesdays, Wednesdays and Thursdays . From milepost 165 to milepost 166&amp;quot;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;               &amp;quot;Latitude&amp;quot;:&amp;quot;47.615975&amp;quot;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;               &amp;quot;Longitude&amp;quot;:&amp;quot;-122.328988&amp;quot;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;               &amp;quot;Direction&amp;quot;:&amp;quot;NB&amp;quot;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;               &amp;quot;Severity&amp;quot; : 2,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;               &amp;quot;ReportDate&amp;quot;:1178600400,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;               &amp;quot;UpdateDate&amp;quot;:1178608793,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;               &amp;quot;EndDate&amp;quot;:1178712000},&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt; &lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;              {&amp;quot;type&amp;quot;:&amp;quot;incident&amp;quot;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;               &amp;quot;Title&amp;quot;:&amp;quot;Lane closed, on WA-99 at 4TH AVE&amp;quot;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;               &amp;quot;Description&amp;quot;:&amp;quot;SR 99 Road construction, right lane closed on SR 99 in both directions from 4TH AVE W to 7TH AVE SE starting 8:00 PM, 05 07 07 for a week from 08:00pm to 06:00am on Mondays, Tuesdays, Wednesdays and Thursdays . From milepost 50 to milepost 51&amp;quot;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;              &amp;quot;Latitude&amp;quot;:&amp;quot;47.634877&amp;quot;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;              &amp;quot;Longitude&amp;quot;:&amp;quot;-122.344338&amp;quot;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;              &amp;quot;Direction&amp;quot;:&amp;quot;N\/A&amp;quot;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;              &amp;quot;Severity&amp;quot;:2,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;              &amp;quot;ReportDate&amp;quot;:1178506800,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;              &amp;quot;UpdateDate&amp;quot;:1178608788,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;              &amp;quot;EndDate&amp;quot;:1178715600}&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;            ]&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;   }&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;}&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt; &lt;/span&gt;
&lt;table style="background:#daeef3;border-collapse:collapse" cellspacing=0 cellpadding=0 border=0&gt;
&lt;tbody&gt;
&lt;tr style=""&gt;
&lt;td valign=top width=798&gt;
&lt;p style="line-height:normal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;lt;/&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;xsl:variable&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt;&lt;/span&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p style="line-height:normal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt; &lt;/span&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt;&lt;/span&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt; 
&lt;p&gt;
&lt;p&gt;Then,&lt;span&gt;  &lt;span&gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;f:json&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;-document($&lt;span&gt;vStr&lt;/span&gt;)&lt;/span&gt;&lt;/strong&gt; evaluates to: 
&lt;p&gt; 
&lt;table cellspacing=0 cellpadding=2 width=802 border=0&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td valign=top width=800&gt;
&lt;table style="border-right:medium none;border-top:medium none;border-left:medium none;border-bottom:medium none;border-collapse:collapse" cellspacing=0 cellpadding=0 border=1&gt;
&lt;tbody&gt;
&lt;tr style=""&gt;
&lt;td valign=top width=798&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;ResultSet&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt;  &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;   &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;LastUpdateDate&lt;/span&gt;&lt;span style="font-size:8.5pt;font-family:'Trebuchet MS','sans-serif'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Trebuchet MS','sans-serif'"&gt;1178683597&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;LastUpdateDate&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;   &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Result&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;type&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;construction&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;type&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:teal;font-family:'Courier New'"&gt;Title&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;Construction work, on I-5 NB at SENECA ST&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;strong&gt;&lt;span style="font-size:10pt;color:teal;font-family:'Courier New'"&gt;Title&lt;/span&gt;&lt;/strong&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Description&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;I 5 N Construction work, Left Lane Blocked on I 5 northbound from Seneca Street to Pine Street starting 11:00 PM, 05 08 07 for several days from 11:00pm to 05:00am on Tuesdays, Wednesdays and Thursdays . From milepost 165 to milepost 167&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Description&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Latitude&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;47.614353&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Latitude&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Longitude&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;-122.329586&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Longitude&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Direction&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;NB&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Direction&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Severity&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;2&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Severity&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;ReportDate&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;1178604000&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;ReportDate&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;UpdateDate&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;1178608792&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;UpdateDate&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;EndDate&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;1178712000&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;EndDate&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;   &amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Result&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;   &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Result&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;type&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;construction&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;type&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:teal;font-family:'Courier New'"&gt;Title&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;Construction work, on I-5 NB at UNIVERSITY ST&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;strong&gt;&lt;span style="font-size:10pt;color:teal;font-family:'Courier New'"&gt;Title&lt;/span&gt;&lt;/strong&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Description&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;I 5 N Construction work, On ramp Blocked on I 5 northbound at University Street starting 10:00 PM, 05 08 07 until further notice from 10:00pm to 05:00am on Tuesdays, Wednesdays and Thursdays . From milepost 165 to milepost 166&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Description&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Latitude&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;47.615975&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Latitude&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Longitude&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;-122.328988&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Longitude&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Direction&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;NB&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Direction&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Severity&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;2&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Severity&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;ReportDate&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;1178600400&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;ReportDate&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;UpdateDate&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;1178608793&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;UpdateDate&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;EndDate&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;1178712000&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;EndDate&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;   &amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Result&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;   &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Result&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;type&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;incident&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;type&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:teal;font-family:'Courier New'"&gt;Title&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;Lane closed, on WA-99 at 4TH AVE&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;strong&gt;&lt;span style="font-size:10pt;color:teal;font-family:'Courier New'"&gt;Title&lt;/span&gt;&lt;/strong&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Description&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;SR 99 Road construction, right lane closed on SR 99 in both directions from 4TH AVE W to 7TH AVE SE starting 8:00 PM, 05 07 07 for a week from 08:00pm to 06:00am on Mondays, Tuesdays, Wednesdays and Thursdays . From milepost 50 to milepost 51&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Description&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Latitude&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;47.634877&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Latitude&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Longitude&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;-122.344338&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Longitude&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Direction&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;N/A&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Direction&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Severity&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;2&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Severity&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;ReportDate&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;1178506800&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;ReportDate&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;UpdateDate&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;1178608788&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;UpdateDate&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;EndDate&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;strong&gt;&lt;span style="font-family:'Courier New'"&gt;1178715600&lt;/span&gt;&lt;/strong&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;EndDate&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;   &amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;Result&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;ResultSet&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt; &lt;/span&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;
&lt;p&gt; &lt;span&gt;and&lt;/span&gt; you can transform nicely this XML document with XSLT now. 
&lt;p&gt;&lt;strong&gt;&lt;span style="background:yellow"&gt;The functions &lt;span&gt;f&lt;span&gt;:json&lt;/span&gt;&lt;/span&gt;-document() and &lt;span&gt;f:json&lt;/span&gt;-file-document() are available immediately &lt;/span&gt;&lt;/strong&gt;from the &lt;a href="http://fxsl.cvs.sourceforge.net/fxsl/?sortby=date"&gt;&lt;strong&gt;CVS&lt;/strong&gt; &lt;/a&gt;of &lt;strong&gt;&lt;a href="http://sourceforge.net/projects/fxsl"&gt;the FXSL project&lt;/a&gt;&lt;/strong&gt;. 
&lt;p&gt;All this &lt;strong&gt;&lt;span style="background:yellow"&gt;pure XSLT &lt;/span&gt;&lt;/strong&gt;&lt;span style="background:yellow"&gt;magic &lt;/span&gt;(and sure, expect more to come) is possible with using the &lt;strong&gt;&lt;a href="http://fxsl.cvs.sourceforge.net/fxsl/fxsl-xslt2/f/func-lrParse.xsl?view=markup&amp;amp;sortby=date"&gt;LR Parsing Framework &lt;/a&gt;&lt;/strong&gt;implemented in &lt;strong&gt;&lt;a href="http://fxsl.sf.net/"&gt;FXSL&lt;/a&gt;&lt;/strong&gt;. 
&lt;p&gt;&lt;strong&gt;&lt;span style="font-size:13.5pt;color:maroon;font-family:'Lucida Handwriting'"&gt;More to come&lt;span&gt;  soon&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span style="font-size:13.5pt;font-family:'Lucida Handwriting'"&gt;.&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=4949635400605856904&amp;page=RSS%3a+Transforming+JSON&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=dnovatchev.spaces.live.com&amp;amp;GT1=dnovatchev"&gt;</description><comments>http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!367.entry#comment</comments><guid isPermaLink="true">http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!367.entry</guid><pubDate>Fri, 06 Jul 2007 04:14:05 GMT</pubDate><slash:comments>1</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://dnovatchev.spaces.live.com/blog/cns!44B0A32C2CCF7488!367/comments/feed.rss</wfw:commentRss><wfw:comment>http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!367.entry#comment</wfw:comment><dcterms:modified>2007-07-06T04:22:44Z</dcterms:modified></item><item><title>Solving Sudoku with a single SQL statement and with a single RegEx</title><link>http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!363.entry</link><description>&lt;div&gt;&lt;font size=3&gt;If you found &lt;/font&gt;&lt;a href="http://ajwelch.blogspot.com/2006/03/dimitres-tuned-sudoku-solution.html"&gt;&lt;font face="Garamond, Times, Serif" size=4&gt;mine&lt;/font&gt;&lt;/a&gt;&lt;font size=3&gt;&lt;font face="Lucida Handwriting, Cursive"&gt; &lt;/font&gt;and &lt;/font&gt;&lt;a href="http://ajwelch.blogspot.com/2006/05/sudoku-solver-complete-and-shes-fast_02.html"&gt;&lt;font face="Garamond, Times, Serif" size=4&gt;Andrew Welch's &lt;/font&gt;&lt;/a&gt;&lt;font size=3&gt;&lt;font face="Garamond, Times, Serif" size=4&gt;  &lt;/font&gt;XSLT Sudoku solvers &lt;font face="Lucida Handwriting, Cursive"&gt;&lt;strong&gt;grotesque&lt;/strong&gt;&lt;/font&gt;,    then hold on:&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;font size=3&gt;&lt;/font&gt; &lt;/div&gt;
&lt;div&gt;&lt;a href="http://technology.amis.nl/blog/?p=2066"&gt;&lt;strong&gt;&lt;font size=3&gt;Here is a Sudoku solver in one SQL statement&lt;/font&gt;&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;&lt;font size=3&gt;.&lt;/font&gt;&lt;/strong&gt;&lt;/div&gt;
&lt;div&gt;&lt;font size=3&gt;&lt;/font&gt; &lt;/div&gt;
&lt;div&gt;&lt;font size=3&gt;What seems even more bizarre is &lt;/font&gt;&lt;a href="http://n01senet.blogspot.com/2007/05/sudoku-by-regex.html"&gt;&lt;strong&gt;&lt;font size=3&gt;this one&lt;/font&gt;&lt;/strong&gt;&lt;/a&gt;&lt;font size=3&gt;, solving Sudoku within &lt;strong&gt;&lt;a href="http://n01se.net/paste/jFa"&gt;a regular expression&lt;/a&gt;&lt;/strong&gt;.&lt;/font&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=4949635400605856904&amp;page=RSS%3a+Solving+Sudoku+with+a+single+SQL+statement+and+with+a+single+RegEx&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=dnovatchev.spaces.live.com&amp;amp;GT1=dnovatchev"&gt;</description><category>Sudoku</category><comments>http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!363.entry#comment</comments><guid isPermaLink="true">http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!363.entry</guid><pubDate>Sun, 10 Jun 2007 04:58:27 GMT</pubDate><slash:comments>2</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://dnovatchev.spaces.live.com/blog/cns!44B0A32C2CCF7488!363/comments/feed.rss</wfw:commentRss><wfw:comment>http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!363.entry#comment</wfw:comment><dcterms:modified>2007-06-10T04:59:25Z</dcterms:modified></item><item><title>XSLT Text Processing: Fun with Anagrams</title><link>http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!357.entry</link><description>&lt;p&gt;After so many nice experiences with XSLT text processing: dictionary lookup, spelling checking and suggesting candidate words, text justifying. text search and replacement, concordance over large corpora, even parsing LR-1 languages, I almost had decided that there was nothing much left to do in this area. 
&lt;p&gt;These days, while some people, who don't know what they are talking about are discussing in the XSL-List &amp;quot;Is XSLT dead?&amp;quot;, it suddenly came to me that yes, there was something left: &lt;strong&gt;&lt;em&gt;finding anagrams&lt;/em&gt;&lt;/strong&gt; 
&lt;p&gt;It turns out that finding anagrams with XSLT is as easy and elegant as shown in the following code: 
&lt;p&gt;  
&lt;table bgcolor="#d2e8e8"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;div&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;xsl:stylesheet &lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;version&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;2.0&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;&lt;br&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt; &lt;/span&gt;&lt;span style="font-size:10pt;color:red;font-family:'Courier New'"&gt;xmlns:xsl&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:red;font-family:'Courier New'"&gt;http://www.w3.org/1999/XSL/Transform&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;&lt;br&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt; &lt;/span&gt;&lt;span style="font-size:10pt;color:red;font-family:'Courier New'"&gt;xmlns:f&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:red;font-family:'Courier New'"&gt;http://fxsl.sf.net/&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;&lt;br&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt; &amp;gt;&lt;br&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt; &amp;lt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;xsl:import &lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;href&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;../f/func-qsort.xsl&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;  &lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt; &amp;lt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;xsl:key &lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;name&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;kAnagram&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot; &lt;/span&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;match&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;w&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot; &lt;br&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;   &lt;/span&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;use&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;codepoints-to-string(f:qsort(string-to-codepoints(.)))&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;&lt;br&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;  /&amp;gt;&lt;/span&gt; 
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt; &amp;lt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;xsl:template &lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;match&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;/&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;&amp;gt;&lt;br&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;   &amp;lt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;xsl:copy-of &lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;select&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;key('kAnagram', 'acert')&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;/&amp;gt;&lt;br&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt; &amp;lt;/&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;xsl:template&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;/span&gt; 
&lt;p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;lt;/&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;xsl:stylesheet&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;/span&gt;  &lt;/div&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;Here, I am reusing the same 46379 English wordforms dictionary, I was using for the spelling checking tasks. In fact, the transformation is applied on it -- the document dictEnglish.xml. Each word has its &lt;strong&gt;&lt;em&gt;Anagram Key&lt;/em&gt;&lt;/strong&gt;, which is the string of the sorted sequence of characters comprising this word. It is easy to see that words, which are anagrams to each other do have the same anagram key. 
&lt;p&gt;The Anagram Key of a word is specified as the following XPath expression: 
&lt;p&gt;  &lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;&lt;strong&gt;codepoints-to-string(f:qsort(string-to-codepoints(.)))&lt;/strong&gt;&lt;/span&gt; 
&lt;p&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;&lt;font face=Verdana color="#444444"&gt;where &lt;strong&gt;&lt;font face="Courier New" color="#000000"&gt;string-to-codepoints()&lt;/font&gt;&lt;/strong&gt;  and &lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;&lt;strong&gt;codepoints-to-string()&lt;/strong&gt;&lt;/span&gt;  are standard XPath 2.0 functions and  &lt;strong&gt;&lt;font face="Courier New" color="#000000"&gt;&lt;a href="http://fxsl.cvs.sourceforge.net/fxsl/fxsl-xslt2/f/func-qsort.xsl?view=markup"&gt;f:qsort()&lt;/a&gt;&lt;/font&gt;&lt;/strong&gt;  is a function from &lt;a href="http://fxsl.sf.net/"&gt;&lt;strong&gt;FXSL&lt;/strong&gt;&lt;/a&gt;.&lt;/font&gt;&lt;/span&gt; 
&lt;p&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;In the code above the English dictionary is indexed using as key (yes!) the Anagram Key for each word. Then we get all words that have the same Anagram Key as the word &amp;quot;trace&amp;quot;. The result is:&lt;/span&gt;  &lt;font color="#0000ff" size=2&gt; 
&lt;p&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000" size=2&gt;w&lt;/font&gt;&lt;font color="#0000ff" size=2&gt;&amp;gt;&lt;/font&gt;&lt;b&gt;&lt;font size=2&gt;&lt;font color="#000000"&gt;caret&lt;/font&gt;&lt;/font&gt;&lt;/b&gt;&lt;font color="#0000ff" size=2&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000" size=2&gt;w&lt;/font&gt;&lt;font color="#0000ff" size=2&gt;&amp;gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000" size=2&gt;w&lt;/font&gt;&lt;font color="#0000ff" size=2&gt;&amp;gt;&lt;/font&gt;&lt;b&gt;&lt;font size=2&gt;&lt;font color="#000000"&gt;cater&lt;/font&gt;&lt;/font&gt;&lt;/b&gt;&lt;font color="#0000ff" size=2&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000" size=2&gt;w&lt;/font&gt;&lt;font color="#0000ff" size=2&gt;&amp;gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000" size=2&gt;w&lt;/font&gt;&lt;font color="#0000ff" size=2&gt;&amp;gt;&lt;/font&gt;&lt;b&gt;&lt;font size=2&gt;&lt;font color="#000000"&gt;crate&lt;/font&gt;&lt;/font&gt;&lt;/b&gt;&lt;font color="#0000ff" size=2&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000" size=2&gt;w&lt;/font&gt;&lt;font color="#0000ff" size=2&gt;&amp;gt;&lt;br&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000" size=2&gt;w&lt;/font&gt;&lt;font color="#0000ff" size=2&gt;&amp;gt;&lt;/font&gt;&lt;b&gt;&lt;font size=2&gt;&lt;font color="#000000"&gt;react&lt;/font&gt;&lt;/font&gt;&lt;/b&gt;&lt;font color="#0000ff" size=2&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000" size=2&gt;w&lt;/font&gt;&lt;font color="#0000ff" size=2&gt;&amp;gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000" size=2&gt;w&lt;/font&gt;&lt;font color="#0000ff" size=2&gt;&amp;gt;&lt;/font&gt;&lt;b&gt;&lt;font size=2&gt;&lt;font color="#000000"&gt;recta&lt;/font&gt;&lt;/font&gt;&lt;/b&gt;&lt;font color="#0000ff" size=2&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000" size=2&gt;w&lt;/font&gt;&lt;font color="#0000ff" size=2&gt;&amp;gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000" size=2&gt;w&lt;/font&gt;&lt;font color="#0000ff" size=2&gt;&amp;gt;&lt;/font&gt;&lt;b&gt;&lt;font size=2&gt;&lt;font color="#000000"&gt;trace&lt;/font&gt;&lt;/font&gt;&lt;/b&gt;&lt;font color="#0000ff" size=2&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000" size=2&gt;w&lt;/font&gt;&lt;font color="#0000ff" size=2&gt;&amp;gt;&lt;/font&gt; 
&lt;p&gt;&lt;font color="#0000ff" size=2&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;While it is nice to be able to implement such functionality just with a few lines of code, it is not wise to index the huge English dictionary each time we need to get some anagrams. In fact this indexing operation takes a lot of time -- in the example above it took about 280 seconds.&lt;/span&gt;&lt;/font&gt; 
&lt;p&gt;&lt;font color="#0000ff" size=2&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;The next logical step is to persist the indexed document into an Anagram Dictionary and reuse it from here on. Here is the XSLT transformation, which creates the Anagram Dictionary:&lt;/span&gt;&lt;/font&gt; 
&lt;p&gt;&lt;font color="#0000ff" size=2&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;
&lt;table bgcolor="#d2e8e8"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;div&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;
&lt;p style="line-height:normal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;xsl:stylesheet &lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;version&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;2.0&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:red;font-family:'Courier New'"&gt;xmlns:xsl&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:red;font-family:'Courier New'"&gt;http://www.w3.org/1999/XSL/Transform&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:red;font-family:'Courier New'"&gt;xmlns:xs&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:red;font-family:'Courier New'"&gt;http://www.w3.org/2001/XMLSchema&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:red;font-family:'Courier New'"&gt;xmlns:f&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:red;font-family:'Courier New'"&gt;http://fxsl.sf.net/&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;exclude-result-prefixes&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;f xs&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt; &lt;/span&gt;&amp;gt;&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt; &lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;xsl:import &lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;href&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;../f/func-standardXSLTXpathFunctions.xsl&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;/&amp;gt;&lt;/span&gt; &lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt; 
&lt;p style="line-height:normal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt; &lt;/span&gt;&amp;lt;!--&lt;/span&gt;&lt;span style="font-size:10pt;color:navy;font-family:'Courier New'"&gt; To be applied on dictEnglish.xml &lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;--&amp;gt;&lt;/span&gt; &lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt; &lt;/span&gt; 
&lt;p style="line-height:normal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt; &lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;xsl:template &lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;match&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;/&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;&amp;gt;&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt;   &lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;anagrams&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;xsl:for-each-group select&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;/*/w&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot; &lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;group-by&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;codepoints-to-string(f:xsltSort(string-to-codepoints(.),&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;                                  &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;(f:_auxInt2Str())&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;                                 &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;)&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt;                             &lt;/span&gt;)&amp;quot;&amp;gt;&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;xsl:sort &lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;select&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;current-grouping-key()&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;/&amp;gt;&lt;/span&gt; 
&lt;p style="line-height:normal"&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;xsl:if &lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;test&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;current-group()[2]&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;&amp;gt;&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;aChain key&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;{current-grouping-key()}&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;&amp;gt;&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;xsl:sequence select&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;current-group()&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;/&amp;gt;&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;aChain&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;xsl:sequence select&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;'&lt;i&gt;&amp;amp;#xA;&lt;/i&gt;'&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;/&amp;gt;&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;&lt;span&gt;           &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;lt;/&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;xsl:if&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;xsl:for-each-group&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt; &lt;br&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt;   &lt;/span&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;anagrams&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt; &lt;/span&gt;&amp;lt;/&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;xsl:template&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;/span&gt; &lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt; 
&lt;p style="line-height:normal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt; &lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;xsl:variable &lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;name&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;vZeroes&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot; &lt;/span&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;select&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;'0000000000'&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot; &lt;br&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt;                              &lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;&lt;font color="#800000"&gt;as&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;xs:string&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;/&amp;gt;&lt;/span&gt; 
&lt;p style="line-height:normal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt; &lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;xsl:function name&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;f:_auxInt2Str&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot; &lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;as&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;xs:string&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;&amp;gt;&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt;   &lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;xsl:param &lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;name&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;arg1&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot; &lt;/span&gt;&lt;span style="font-size:10pt;color:white;font-family:'Courier New'"&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;&lt;font color="#800000"&gt;as&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;xs:integer&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;/&amp;gt;&lt;/span&gt; &lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt;   &lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;xsl:variable &lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;name&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;vstrParm&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot; &lt;/span&gt;&lt;span style="font-size:10pt;color:white;font-family:'Courier New'"&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;&lt;font color="#800000"&gt;as&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;xs:string&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;color:purple;font-family:'Courier New'"&gt;select&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;xs:string($arg1)&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;/&amp;gt;&lt;/span&gt; &lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;
&lt;p style="line-height:normal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt;   &lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;xsl:sequence select&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt;    &lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;concat(substring($vZeroes,1, &lt;br&gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;&lt;span&gt;                      &lt;/span&gt;10 - string-length($vstrParm)&lt;/span&gt;&lt;/b&gt; &lt;br&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;&lt;span&gt;                      &lt;/span&gt;), &lt;br&gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;&lt;span&gt;            &lt;/span&gt;$vstrParm&lt;/span&gt;&lt;/b&gt; &lt;br&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;&lt;span&gt;            &lt;/span&gt;)&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot;&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt;    &lt;/span&gt;/&amp;gt;&lt;/span&gt; &lt;br&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt; &lt;/span&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;xsl:function&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;gt;&lt;/span&gt; &lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt; 
&lt;p style="line-height:normal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&lt;span&gt; &lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size:10pt;color:maroon;font-family:'Courier New'"&gt;xsl:function name&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;=&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:10pt;color:black;font-family:'Courier New'"&gt;f:_auxInt2Str&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New'"&gt;&amp;quot; &l