<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:georss="http://www.georss.org/georss" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Nesterovsky bros - xslt</title>
    <link>http://www.nesterovsky-bros.com/weblog/</link>
    <description />
    <language>en-us</language>
    <copyright>Nesterovsky bros</copyright>
    <lastBuildDate>Mon, 29 Oct 2012 15:34:38 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.12105.0</generator>
    <managingEditor>contact@nesterovsky-bros.com</managingEditor>
    <webMaster>contact@nesterovsky-bros.com</webMaster>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=98b58257-9069-4d13-9d10-a7061e14e834</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,98b58257-9069-4d13-9d10-a7061e14e834.aspx</pingback:target>
      <dc:creator>Arthur Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,98b58257-9069-4d13-9d10-a7061e14e834.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=98b58257-9069-4d13-9d10-a7061e14e834</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
If you deal with web applications you probably have already dealt with export data
to Excel. There are several options to prepare data for Excel:
</p>
        <ul>
          <li>
generate CSV;</li>
          <li>
generate HTML that excel understands;</li>
          <li>
generate XML in Spreadsheet 2003 format;</li>
          <li>
generate data using Open XML SDK or some other 3rd party libraries;</li>
          <li>
generate data in XLSX format, according to Open XML specification.</li>
        </ul>
        <p>
You may find a good article with pros and cons of each solution <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=98b58257-9069-4d13-9d10-a7061e14e834&amp;url=http%3a%2f%2fblogs.msdn.com%2fb%2ferikaehrli%2farchive%2f2009%2f01%2f30%2fhow-to-export-data-to-excel-from-an-asp-net-application-avoid-the-file-format-differ-prompt.aspx" target="_blank">here</a>.
We, in our turn, would like to share our experience in this field. Let's start from
requirements:
</p>
        <ul>
          <li>
Often we have to export huge data-sets.</li>
          <li>
We should be able to format, parametrize and to apply different styles to the exported
data.</li>
          <li>
There are cases when exported data may contain more than one table per sheet or even
more than one sheet.</li>
          <li>
Some exported data have to be illustrated with charts.</li>
        </ul>
        <p>
All these requirements led us to a solution based on XSLT processing of streamed data.
The advantage of this solution is that the result is immediately forwarded to a client
as fast as XSLT starts to generate output. Such approach is much productive than generating
of XLSX using of Open XML SDK or any other third party library, since it avoids keeping
a huge data-sets in memory on the server side.
</p>
        <p style="direction: ltr">
Another advantage - is simple maintenance, as we achieve clear separation of data
and presentation layers. On each request to change formatting or apply another style
to a cell you just have to modify xslt file(s) that generate variable parts of XLSX.
</p>
        <p>
As result, our clients get XLSX files according with Open XML specifications. The
details of implementations of our solution see in our next posts.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=98b58257-9069-4d13-9d10-a7061e14e834" />
      </body>
      <title>Export data to Excel</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,98b58257-9069-4d13-9d10-a7061e14e834.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2012/10/29/ExportDataToExcel.aspx</link>
      <pubDate>Mon, 29 Oct 2012 15:34:38 GMT</pubDate>
      <description>&lt;p&gt;
If you deal with web applications you probably have already dealt with export data
to Excel. There are several options to prepare data for Excel:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
generate CSV;&lt;/li&gt;
&lt;li&gt;
generate HTML that excel understands;&lt;/li&gt;
&lt;li&gt;
generate XML in Spreadsheet 2003 format;&lt;/li&gt;
&lt;li&gt;
generate data using Open XML SDK or some other 3rd party libraries;&lt;/li&gt;
&lt;li&gt;
generate data in XLSX format, according to Open XML specification.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
You may find a good article with pros and cons of each solution &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=98b58257-9069-4d13-9d10-a7061e14e834&amp;amp;url=http%3a%2f%2fblogs.msdn.com%2fb%2ferikaehrli%2farchive%2f2009%2f01%2f30%2fhow-to-export-data-to-excel-from-an-asp-net-application-avoid-the-file-format-differ-prompt.aspx" target="_blank"&gt;here&lt;/a&gt;.
We, in our turn, would like to share our experience in this field. Let's start from
requirements:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Often we have to export huge data-sets.&lt;/li&gt;
&lt;li&gt;
We should be able to format, parametrize and to apply different styles to the exported
data.&lt;/li&gt;
&lt;li&gt;
There are cases when exported data may contain more than one table per sheet or even
more than one sheet.&lt;/li&gt;
&lt;li&gt;
Some exported data have to be illustrated with charts.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
All these requirements led us to a solution based on XSLT processing of streamed data.
The advantage of this solution is that the result is immediately forwarded to a client
as fast as XSLT starts to generate output. Such approach is much productive than generating
of XLSX using of Open XML SDK or any other third party library, since it avoids keeping
a huge data-sets in memory on the server side.
&lt;/p&gt;
&lt;p style="direction: ltr"&gt;
Another advantage - is simple maintenance, as we achieve clear separation of data
and presentation layers. On each request to change formatting or apply another style
to a cell you just have to modify xslt file(s) that generate variable parts of XLSX.
&lt;/p&gt;
&lt;p&gt;
As result, our clients get XLSX files according with Open XML specifications. The
details of implementations of our solution see in our next posts.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=98b58257-9069-4d13-9d10-a7061e14e834" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,98b58257-9069-4d13-9d10-a7061e14e834.aspx</comments>
      <category>.NET</category>
      <category>ASP.NET</category>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=cad54317-1876-4b98-a8d2-7e44e5dda1f7</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,cad54317-1876-4b98-a8d2-7e44e5dda1f7.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,cad54317-1876-4b98-a8d2-7e44e5dda1f7.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=cad54317-1876-4b98-a8d2-7e44e5dda1f7</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Earlier we have shown <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=cad54317-1876-4b98-a8d2-7e44e5dda1f7&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2012%2f07%2f22%2fStreamingEntityData.aspx"> how
to build streaming xml reader from business data</a> and have reminded about <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=cad54317-1876-4b98-a8d2-7e44e5dda1f7&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2012%2f07%2f26%2fStreamingXsltTransformationWithForwardXPathNavigator.aspx">ForwardXPathNavigator
which helps to create a streaming xslt transformation</a>. Now we want to show how
to stream content produced with xslt out of WCF service.
</p>
        <p>
To achieve streaming in WCF one needs: 
</p>
        <p>
1. To configure service to use streaming. Description on how to do this can be found
in the internet. See web.config of the sample <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=cad54317-1876-4b98-a8d2-7e44e5dda1f7&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fStreaming.zip"> Streaming.zip</a> for
the details.
</p>
        <p>
2. Create a service with a method returning <code>Stream</code>:
</p>
        <p>
          <code>[ServiceContract(Namespace = "http://www.nesterovsky-bros.com")]<br />
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]<br />
public class Service<br />
{<br />
[OperationContract]<br />
[WebGet(RequestFormat = WebMessageFormat.Json)]<br />
public Stream GetPeopleHtml(int count, int seed)<br />
{<br />
...<br />
}<br />
}</code>
        </p>
        <p>
2. Return a <code>Stream</code> from xsl transformation. 
</p>
        <p>
Unfortunately (we mentioned it already), <code>XslCompiledTransform</code> generates
its output into <code>XmlWriter</code> (or into output <code>Stream</code>) rather
than exposes result as <code>XmlReader</code>, while WCF gets input stream and passes
it to a client. 
</p>
        <p>
We could generate xslt output into a file or a memory <code>Stream</code> and then
return that content as input <code>Stream</code>, but this will defeat a goal of streaming,
as client would have started to get data no earlier that the xslt completed its work.
What we need instead is a pipe that form xslt output <code>Stream</code> to an input <code>Stream</code> returned
from WCF.
</p>
        <p>
.NET implements pipe streams, so our task is trivial. We have defined a utility method
that creates an input <code>Stream</code> from a generator populating an output <code>Stream</code>:
</p>
        <p>
          <code> public static Stream GetPipedStream(Action&lt;Stream&gt; generator)<br />
{<br />
var output = new AnonymousPipeServerStream();<br />
var input = new AnonymousPipeClientStream(<br />
output.GetClientHandleAsString());<br /><br />
Task.Factory.StartNew(<br />
() =&gt;<br />
{<br />
using(output)<br />
{<br />
generator(output);<br />
output.WaitForPipeDrain();<br />
}<br />
},<br />
TaskCreationOptions.LongRunning);<br /><br />
return input;<br />
} </code>
        </p>
        <p>
We wrapped xsl transformation as such a generator:
</p>
        <p>
          <code>[OperationContract]<br />
[WebGet(RequestFormat = WebMessageFormat.Json)]<br />
public Stream GetPeopleHtml(int count, int seed)<br />
{<br />
var context = WebOperationContext.Current;<br /><br />
context.OutgoingResponse.ContentType = "text/html";<br />
context.OutgoingResponse.Headers["Content-Disposition"] = 
<br />
"attachment;filename=reports.html";<br /><br />
var cache = HttpRuntime.Cache;<br />
var path = HttpContext.Current.Server.MapPath("~/People.xslt");<br />
var transform = cache[path] as XslCompiledTransform;<br /><br />
if (transform == null)<br />
{<br />
transform = new XslCompiledTransform();<br />
transform.Load(path);<br />
cache.Insert(path, transform, new CacheDependency(path));<br />
}<br /><br />
return Extensions.<strong>GetPipedStream</strong>(<br />
output =&gt;<br />
{<br />
// We have a streamed business data.<br />
var people = Data.CreateRandomData(count, seed, 0, count);<br /><br />
// We want to see it as streamed xml data.<br />
using(var stream =<br />
people.<strong>ToXmlStream</strong>("people", "http://www.nesterovsky-bros.com"))<br />
using(var reader = XmlReader.Create(stream))<br />
{<br />
// XPath forward navigator is used as an input source.<br />
transform.Transform(<br />
new <strong>ForwardXPathNavigator</strong>(reader),<br />
new XsltArgumentList(),<br />
output);<br />
}<br />
});<br />
}</code>
        </p>
        <p>
This way we have build a code that streams data directly from business data to a client
in a form of report. A set of utility functions and classes helped us to overcome
.NET's limitations and to build simple code that one can easily support.
</p>
        <p>
The sources can be found at <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=cad54317-1876-4b98-a8d2-7e44e5dda1f7&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fStreaming.zip"> Streaming.zip</a>.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=cad54317-1876-4b98-a8d2-7e44e5dda1f7" />
      </body>
      <title>Stream xslt transformation through WCF</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,cad54317-1876-4b98-a8d2-7e44e5dda1f7.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2012/08/03/StreamXsltTransformationThroughWCF.aspx</link>
      <pubDate>Fri, 03 Aug 2012 22:32:49 GMT</pubDate>
      <description>  &lt;p&gt;
Earlier we have shown &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=cad54317-1876-4b98-a8d2-7e44e5dda1f7&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2012%2f07%2f22%2fStreamingEntityData.aspx"&gt; how
to build streaming xml reader from business data&lt;/a&gt; and have reminded about &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=cad54317-1876-4b98-a8d2-7e44e5dda1f7&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2012%2f07%2f26%2fStreamingXsltTransformationWithForwardXPathNavigator.aspx"&gt;ForwardXPathNavigator
which helps to create a streaming xslt transformation&lt;/a&gt;. Now we want to show how
to stream content produced with xslt out of WCF service.
&lt;/p&gt;
&lt;p&gt;
To achieve streaming in WCF one needs: 
&lt;/p&gt;
&lt;p&gt;
1. To configure service to use streaming. Description on how to do this can be found
in the internet. See web.config of the sample &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=cad54317-1876-4b98-a8d2-7e44e5dda1f7&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fStreaming.zip"&gt; Streaming.zip&lt;/a&gt; for
the details.
&lt;/p&gt;
&lt;p&gt;
2. Create a service with a method returning &lt;code&gt;Stream&lt;/code&gt;:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt;[ServiceContract(Namespace = "http://www.nesterovsky-bros.com")]&lt;br /&gt;
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]&lt;br /&gt;
public class Service&lt;br /&gt;
{&lt;br /&gt;
[OperationContract]&lt;br /&gt;
[WebGet(RequestFormat = WebMessageFormat.Json)]&lt;br /&gt;
public Stream GetPeopleHtml(int count, int seed)&lt;br /&gt;
{&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
}&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
2. Return a &lt;code&gt;Stream&lt;/code&gt; from xsl transformation. 
&lt;/p&gt;
&lt;p&gt;
Unfortunately (we mentioned it already), &lt;code&gt;XslCompiledTransform&lt;/code&gt; generates
its output into &lt;code&gt;XmlWriter&lt;/code&gt; (or into output &lt;code&gt;Stream&lt;/code&gt;) rather
than exposes result as &lt;code&gt;XmlReader&lt;/code&gt;, while WCF gets input stream and passes
it to a client. 
&lt;/p&gt;
&lt;p&gt;
We could generate xslt output into a file or a memory &lt;code&gt;Stream&lt;/code&gt; and then
return that content as input &lt;code&gt;Stream&lt;/code&gt;, but this will defeat a goal of streaming,
as client would have started to get data no earlier that the xslt completed its work.
What we need instead is a pipe that form xslt output &lt;code&gt;Stream&lt;/code&gt; to an input &lt;code&gt;Stream&lt;/code&gt; returned
from WCF.
&lt;/p&gt;
&lt;p&gt;
.NET implements pipe streams, so our task is trivial. We have defined a utility method
that creates an input &lt;code&gt;Stream&lt;/code&gt; from a generator populating an output &lt;code&gt;Stream&lt;/code&gt;:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt; public static Stream GetPipedStream(Action&amp;lt;Stream&amp;gt; generator)&lt;br /&gt;
{&lt;br /&gt;
var output = new AnonymousPipeServerStream();&lt;br /&gt;
var input = new AnonymousPipeClientStream(&lt;br /&gt;
output.GetClientHandleAsString());&lt;br /&gt;
&lt;br /&gt;
Task.Factory.StartNew(&lt;br /&gt;
() =&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
using(output)&lt;br /&gt;
{&lt;br /&gt;
generator(output);&lt;br /&gt;
output.WaitForPipeDrain();&lt;br /&gt;
}&lt;br /&gt;
},&lt;br /&gt;
TaskCreationOptions.LongRunning);&lt;br /&gt;
&lt;br /&gt;
return input;&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
We wrapped xsl transformation as such a generator:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt;[OperationContract]&lt;br /&gt;
[WebGet(RequestFormat = WebMessageFormat.Json)]&lt;br /&gt;
public Stream GetPeopleHtml(int count, int seed)&lt;br /&gt;
{&lt;br /&gt;
var context = WebOperationContext.Current;&lt;br /&gt;
&lt;br /&gt;
context.OutgoingResponse.ContentType = "text/html";&lt;br /&gt;
context.OutgoingResponse.Headers["Content-Disposition"] = 
&lt;br /&gt;
"attachment;filename=reports.html";&lt;br /&gt;
&lt;br /&gt;
var cache = HttpRuntime.Cache;&lt;br /&gt;
var path = HttpContext.Current.Server.MapPath("~/People.xslt");&lt;br /&gt;
var transform = cache[path] as XslCompiledTransform;&lt;br /&gt;
&lt;br /&gt;
if (transform == null)&lt;br /&gt;
{&lt;br /&gt;
transform = new XslCompiledTransform();&lt;br /&gt;
transform.Load(path);&lt;br /&gt;
cache.Insert(path, transform, new CacheDependency(path));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return Extensions.&lt;strong&gt;GetPipedStream&lt;/strong&gt;(&lt;br /&gt;
output =&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
// We have a streamed business data.&lt;br /&gt;
var people = Data.CreateRandomData(count, seed, 0, count);&lt;br /&gt;
&lt;br /&gt;
// We want to see it as streamed xml data.&lt;br /&gt;
using(var stream =&lt;br /&gt;
people.&lt;strong&gt;ToXmlStream&lt;/strong&gt;("people", "http://www.nesterovsky-bros.com"))&lt;br /&gt;
using(var reader = XmlReader.Create(stream))&lt;br /&gt;
{&lt;br /&gt;
// XPath forward navigator is used as an input source.&lt;br /&gt;
transform.Transform(&lt;br /&gt;
new &lt;strong&gt;ForwardXPathNavigator&lt;/strong&gt;(reader),&lt;br /&gt;
new XsltArgumentList(),&lt;br /&gt;
output);&lt;br /&gt;
}&lt;br /&gt;
});&lt;br /&gt;
}&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
This way we have build a code that streams data directly from business data to a client
in a form of report. A set of utility functions and classes helped us to overcome
.NET&amp;#39;s limitations and to build simple code that one can easily support.
&lt;/p&gt;
&lt;p&gt;
The sources can be found at &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=cad54317-1876-4b98-a8d2-7e44e5dda1f7&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fStreaming.zip"&gt; Streaming.zip&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=cad54317-1876-4b98-a8d2-7e44e5dda1f7" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,cad54317-1876-4b98-a8d2-7e44e5dda1f7.aspx</comments>
      <category>.NET</category>
      <category>ASP.NET</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=24094700-ca7e-4e73-8b30-fbdc9d72072a</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,24094700-ca7e-4e73-8b30-fbdc9d72072a.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,24094700-ca7e-4e73-8b30-fbdc9d72072a.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=24094700-ca7e-4e73-8b30-fbdc9d72072a</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In the previous <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=24094700-ca7e-4e73-8b30-fbdc9d72072a&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2012%2f07%2f22%2fStreamingEntityData.aspx"> post
about streaming</a> we have dropped at the point where we have <code>XmlReader</code> in
hands, which continously gets data from <code>IEnumerable&lt;Person&gt;</code> source.
Now we shall remind about <code>ForwardXPathNavigator</code> - a class we have built
back in 2002, which adds streaming transformations to .NET's xslt processor.
</p>
        <p>
While <code>XslCompiledTransform</code> is desperately obsolete, and no upgrade will
possibly follow; still it's among the fastest xslt 1.0 processors. With <code> ForwardXPathNavigator</code> we
add ability to transform input data of arbitrary size to this processor.
</p>
        <p>
We find it interesting that <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=24094700-ca7e-4e73-8b30-fbdc9d72072a&amp;url=http%3a%2f%2fwww.w3.org%2fTR%2fxslt-30%2f%23streaming-concepts"> xslt
3.0 Working Draft defines streaming processing</a> in a way that closely matches rules
for <code>ForwardXPathNavigator</code>:
</p>
        <div style="padding-left: 1em; font-style: italic">
          <p>
Streaming achieves two important objectives: it allows large documents to be transformed
without requiring correspondingly large amounts of memory; and it allows the processor
to start producing output before it has finished receiving its input, thus reducing
latency.
</p>
          <p>
The rules for streamability, which are defined in detail in <i>19.3 Streamability
Analysis</i>, impose two main constraints:
</p>
          <ul>
            <li>
              <p>
The only nodes reachable from the node that is currently being processed are its attributes
and namespaces, its ancestors and their attributes and namespaces, and its descendants
and their attributes and namespaces. The siblings of the node, and the siblings of
its ancestors, are not reachable in the tree, and any attempt to use their values
is a static error. However, constructs (for example, simple forms of <code>xsl:number</code>,
and simple positional patterns) that require knowledge of the number of preceding
elements by name are permitted.
</p>
            </li>
            <li>
              <p>
When processing a given node in the tree, each descendant node can only be visited
once. Essentially this allows two styles of processing: either visit each of the children
once, and then process that child with the same restrictions applied; or process all
the descendants in a single pass, in which case it is not possible while processing
a descendant to make any further downward selection.
</p>
            </li>
          </ul>
        </div>
        <p>
The only significant difference between <code>ForwardXPathNavigator</code> and xlst
3.0 streaming is in that we reported violations of rules for streamability at runtime,
while xslt 3.0 attempts to perform this analysis at compile time.
</p>
        <p>
Here the C# code for the xslt streamed transformation:
</p>
        <p>
          <code> var transform = new XslCompiledTransform();<br /><br />
transform.Load("People.xslt");<br /><br />
// We have a streamed business data.<br />
var people = Data.CreateRandomData(10000, 0, 0, 10000);<br /><br />
// We want to see it as streamed xml data.<br />
using(var stream =<br />
people.ToXmlStream("people", "http://www.nesterovsky-bros.com"))<br />
using(var reader = XmlReader.Create(stream))<br />
using(var output = File.Create("people.html"))<br />
{<br />
// XPath forward navigator is used as an input source.<br />
transform.Transform(<br /><strong>new ForwardXPathNavigator(reader)</strong>,<br />
new XsltArgumentList(),<br />
output);<br />
} </code>
        </p>
        <p>
Notice how <code>XmlReader</code> is wrapped into <code>ForwardXPathNavigator</code>.
</p>
        <p>
To complete the picture we need xslt that follows the streaming rules:
</p>
        <p>
          <code>&lt;xsl:stylesheet version="1.0" xmlns:xsl="<a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=24094700-ca7e-4e73-8b30-fbdc9d72072a&amp;url=http%3a%2f%2fwww.w3.org%2f1999%2fXSL%2fTransform">http://www.w3.org/1999/XSL/Transform</a>"<br />
xmlns:msxsl="urn:schemas-microsoft-com:xslt"<br />
xmlns:d="<a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=24094700-ca7e-4e73-8b30-fbdc9d72072a&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com">http://www.nesterovsky-bros.com</a>"<br />
exclude-result-prefixes="msxsl d"&gt;<br /><br />
&lt;xsl:output method="html" indent="yes"/&gt;<br /><br />
&lt;!-- Root template processed in the streaming mode. --&gt;<br />
&lt;xsl:template match="/d:people"&gt;<br />
&lt;html&gt;<br />
&lt;head&gt;<br />
&lt;title&gt;List of persons&lt;/title&gt;<br />
&lt;style type="text/css"&gt;<br />
.even<br />
{<br />
}<br /><br />
.odd<br />
{<br />
background: #d0d0d0;<br />
}<br />
&lt;/style&gt;<br />
&lt;/head&gt;<br />
&lt;body&gt;<br />
&lt;table border="1"&gt;<br />
&lt;tr&gt;<br />
&lt;th&gt;ID&lt;/th&gt;<br />
&lt;th&gt;First name&lt;/th&gt;<br />
&lt;th&gt;Last name&lt;/th&gt;<br />
&lt;th&gt;City&lt;/th&gt;<br />
&lt;th&gt;Title&lt;/th&gt;<br />
&lt;th&gt;Age&lt;/th&gt;<br />
&lt;/tr&gt;<br /><br />
&lt;xsl:for-each select="d:person"&gt;<br />
&lt;!-- 
<br />
Get element snapshot.<br />
A snapshot allows arbitrary access to the element's content.<br />
--&gt;<br />
&lt;xsl:variable name="person"&gt;<br />
&lt;xsl:copy-of select="."/&gt;<br />
&lt;/xsl:variable&gt;<br /><br />
&lt;xsl:variable name="position" select="position()"/&gt;<br /><br />
&lt;xsl:apply-templates mode="snapshot" select="msxsl:node-set($person)/d:person"&gt;<br />
&lt;xsl:with-param name="position" select="$position"/&gt;<br />
&lt;/xsl:apply-templates&gt;<br />
&lt;/xsl:for-each&gt;<br />
&lt;/table&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;<br />
&lt;/xsl:template&gt;<br /><br />
&lt;xsl:template mode="snapshot" match="d:person"&gt;<br />
&lt;xsl:param name="position"/&gt;<br /><br />
&lt;tr&gt;<br />
&lt;xsl:attribute name="class"&gt;<br />
&lt;xsl:choose&gt;<br />
&lt;xsl:when test="$position mod 2 = 1"&gt;<br />
&lt;xsl:text&gt;odd&lt;/xsl:text&gt;<br />
&lt;/xsl:when&gt;<br />
&lt;xsl:otherwise&gt;<br />
&lt;xsl:text&gt;even&lt;/xsl:text&gt;<br />
&lt;/xsl:otherwise&gt;<br />
&lt;/xsl:choose&gt;<br />
&lt;/xsl:attribute&gt;<br /><br />
&lt;td&gt;<br />
&lt;xsl:value-of select="d:Id"/&gt;<br />
&lt;/td&gt;<br />
&lt;td&gt;<br />
&lt;xsl:value-of select="d:FirstName"/&gt;<br />
&lt;/td&gt;<br />
&lt;td&gt;<br />
&lt;xsl:value-of select="d:LastName"/&gt;<br />
&lt;/td&gt;<br />
&lt;td&gt;<br />
&lt;xsl:value-of select="d:City"/&gt;<br />
&lt;/td&gt;<br />
&lt;td&gt;<br />
&lt;xsl:value-of select="d:Title"/&gt;<br />
&lt;/td&gt;<br />
&lt;td&gt;<br />
&lt;xsl:value-of select="d:Age"/&gt;<br />
&lt;/td&gt;<br />
&lt;/tr&gt;<br />
&lt;/xsl:template&gt;<br /><br />
&lt;/xsl:stylesheet&gt;</code>
        </p>
        <p>
So, we have started with a streamed entity data, proceeded to the streamed XmlReader
and reached to the streamed xslt transformation.
</p>
        <p>
But at the final post about streaming we shall remind a simple way of building WCF
service returning html stream from our xslt transformation.
</p>
        <p>
The sources can be found at <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=24094700-ca7e-4e73-8b30-fbdc9d72072a&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fStreaming.zip"> Streaming.zip</a>.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=24094700-ca7e-4e73-8b30-fbdc9d72072a" />
      </body>
      <title>Streaming xslt transformation with ForwardXPathNavigator</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,24094700-ca7e-4e73-8b30-fbdc9d72072a.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2012/07/26/StreamingXsltTransformationWithForwardXPathNavigator.aspx</link>
      <pubDate>Thu, 26 Jul 2012 18:49:51 GMT</pubDate>
      <description>&lt;p&gt;
In the previous &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=24094700-ca7e-4e73-8b30-fbdc9d72072a&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2012%2f07%2f22%2fStreamingEntityData.aspx"&gt; post
about streaming&lt;/a&gt; we have dropped at the point where we have &lt;code&gt;XmlReader&lt;/code&gt; in
hands, which continously gets data from &lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;&lt;/code&gt; source.
Now we shall remind about &lt;code&gt;ForwardXPathNavigator&lt;/code&gt; - a class we have built
back in 2002, which adds streaming transformations to .NET&amp;#39;s xslt processor.
&lt;/p&gt;
&lt;p&gt;
While &lt;code&gt;XslCompiledTransform&lt;/code&gt; is desperately obsolete, and no upgrade will
possibly follow; still it&amp;#39;s among the fastest xslt 1.0 processors. With &lt;code&gt; ForwardXPathNavigator&lt;/code&gt; we
add ability to transform input data of arbitrary size to this processor.
&lt;/p&gt;
&lt;p&gt;
We find it interesting that &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=24094700-ca7e-4e73-8b30-fbdc9d72072a&amp;amp;url=http%3a%2f%2fwww.w3.org%2fTR%2fxslt-30%2f%23streaming-concepts"&gt; xslt
3.0 Working Draft defines streaming processing&lt;/a&gt; in a way that closely matches rules
for &lt;code&gt;ForwardXPathNavigator&lt;/code&gt;:
&lt;/p&gt;
&lt;div style="padding-left: 1em; font-style: italic"&gt;
&lt;p&gt;
Streaming achieves two important objectives: it allows large documents to be transformed
without requiring correspondingly large amounts of memory; and it allows the processor
to start producing output before it has finished receiving its input, thus reducing
latency.
&lt;/p&gt;
&lt;p&gt;
The rules for streamability, which are defined in detail in &lt;i&gt;19.3 Streamability
Analysis&lt;/i&gt;, impose two main constraints:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
The only nodes reachable from the node that is currently being processed are its attributes
and namespaces, its ancestors and their attributes and namespaces, and its descendants
and their attributes and namespaces. The siblings of the node, and the siblings of
its ancestors, are not reachable in the tree, and any attempt to use their values
is a static error. However, constructs (for example, simple forms of &lt;code&gt;xsl:number&lt;/code&gt;,
and simple positional patterns) that require knowledge of the number of preceding
elements by name are permitted.
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
When processing a given node in the tree, each descendant node can only be visited
once. Essentially this allows two styles of processing: either visit each of the children
once, and then process that child with the same restrictions applied; or process all
the descendants in a single pass, in which case it is not possible while processing
a descendant to make any further downward selection.
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;
The only significant difference between &lt;code&gt;ForwardXPathNavigator&lt;/code&gt; and xlst
3.0 streaming is in that we reported violations of rules for streamability at runtime,
while xslt 3.0 attempts to perform this analysis at compile time.
&lt;/p&gt;
&lt;p&gt;
Here the C# code for the xslt streamed transformation:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt; var transform = new XslCompiledTransform();&lt;br /&gt;
&lt;br /&gt;
transform.Load("People.xslt");&lt;br /&gt;
&lt;br /&gt;
// We have a streamed business data.&lt;br /&gt;
var people = Data.CreateRandomData(10000, 0, 0, 10000);&lt;br /&gt;
&lt;br /&gt;
// We want to see it as streamed xml data.&lt;br /&gt;
using(var stream =&lt;br /&gt;
people.ToXmlStream("people", "http://www.nesterovsky-bros.com"))&lt;br /&gt;
using(var reader = XmlReader.Create(stream))&lt;br /&gt;
using(var output = File.Create("people.html"))&lt;br /&gt;
{&lt;br /&gt;
// XPath forward navigator is used as an input source.&lt;br /&gt;
transform.Transform(&lt;br /&gt;
&lt;strong&gt;new ForwardXPathNavigator(reader)&lt;/strong&gt;,&lt;br /&gt;
new XsltArgumentList(),&lt;br /&gt;
output);&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Notice how &lt;code&gt;XmlReader&lt;/code&gt; is wrapped into &lt;code&gt;ForwardXPathNavigator&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
To complete the picture we need xslt that follows the streaming rules:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt;&amp;lt;xsl:stylesheet version="1.0" xmlns:xsl="&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=24094700-ca7e-4e73-8b30-fbdc9d72072a&amp;amp;url=http%3a%2f%2fwww.w3.org%2f1999%2fXSL%2fTransform"&gt;http://www.w3.org/1999/XSL/Transform&lt;/a&gt;"&lt;br /&gt;
xmlns:msxsl="urn:schemas-microsoft-com:xslt"&lt;br /&gt;
xmlns:d="&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=24094700-ca7e-4e73-8b30-fbdc9d72072a&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com"&gt;http://www.nesterovsky-bros.com&lt;/a&gt;"&lt;br /&gt;
exclude-result-prefixes="msxsl d"&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;xsl:output method="html" indent="yes"/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Root template processed in the streaming mode. --&amp;gt;&lt;br /&gt;
&amp;lt;xsl:template match="/d:people"&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;List of persons&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style type="text/css"&amp;gt;&lt;br /&gt;
.even&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.odd&lt;br /&gt;
{&lt;br /&gt;
background: #d0d0d0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;table border="1"&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;ID&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;First name&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Last name&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;City&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Title&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Age&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;xsl:for-each select="d:person"&amp;gt;&lt;br /&gt;
&amp;lt;!-- 
&lt;br /&gt;
Get element snapshot.&lt;br /&gt;
A snapshot allows arbitrary access to the element&amp;#39;s content.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;xsl:variable name="person"&amp;gt;&lt;br /&gt;
&amp;lt;xsl:copy-of select="."/&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:variable&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;xsl:variable name="position" select="position()"/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;xsl:apply-templates mode="snapshot" select="msxsl:node-set($person)/d:person"&amp;gt;&lt;br /&gt;
&amp;lt;xsl:with-param name="position" select="$position"/&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:apply-templates&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:for-each&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;xsl:template mode="snapshot" match="d:person"&amp;gt;&lt;br /&gt;
&amp;lt;xsl:param name="position"/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;xsl:attribute name="class"&amp;gt;&lt;br /&gt;
&amp;lt;xsl:choose&amp;gt;&lt;br /&gt;
&amp;lt;xsl:when test="$position mod 2 = 1"&amp;gt;&lt;br /&gt;
&amp;lt;xsl:text&amp;gt;odd&amp;lt;/xsl:text&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:when&amp;gt;&lt;br /&gt;
&amp;lt;xsl:otherwise&amp;gt;&lt;br /&gt;
&amp;lt;xsl:text&amp;gt;even&amp;lt;/xsl:text&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:otherwise&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:choose&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:attribute&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&amp;lt;xsl:value-of select="d:Id"/&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&amp;lt;xsl:value-of select="d:FirstName"/&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&amp;lt;xsl:value-of select="d:LastName"/&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&amp;lt;xsl:value-of select="d:City"/&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&amp;lt;xsl:value-of select="d:Title"/&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&amp;lt;xsl:value-of select="d:Age"/&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/xsl:stylesheet&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
So, we have started with a streamed entity data, proceeded to the streamed XmlReader
and reached to the streamed xslt transformation.
&lt;/p&gt;
&lt;p&gt;
But at the final post about streaming we shall remind a simple way of building WCF
service returning html stream from our xslt transformation.
&lt;/p&gt;
&lt;p&gt;
The sources can be found at &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=24094700-ca7e-4e73-8b30-fbdc9d72072a&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fStreaming.zip"&gt; Streaming.zip&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=24094700-ca7e-4e73-8b30-fbdc9d72072a" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,24094700-ca7e-4e73-8b30-fbdc9d72072a.aspx</comments>
      <category>.NET</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=60b3cb37-5da9-4f28-a35f-38d1ef3cccce</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,60b3cb37-5da9-4f28-a35f-38d1ef3cccce.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,60b3cb37-5da9-4f28-a35f-38d1ef3cccce.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=60b3cb37-5da9-4f28-a35f-38d1ef3cccce</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
For some reason neither .NET's <code>XmlSerializer</code> nor <code>DataContractSerializer</code> allow
reading data through an <code>XmlReader</code>. These APIs work other way round writing
data into an <code>XmlWriter</code>. To get data through <code>XmlReader</code> one
needs to write it to some destination like a file or memory stream, and then to read
it using <code>XmlReader</code>. This complicates streaming design considerably.
</p>
        <p>
In fact the very same happens with other .NET APIs.
</p>
        <p>
We think the reason of why .NET designers preferred <code>XmlWriter</code> to <code>XmlReader</code> in
those APIs is that <code>XmlReader</code>'s implementation is a state machine
like, while <code>XmlWriter</code>'s implementation looks like a regular procedure.
It's much harder to <strong>manually</strong> write and to support a correct state
machine logic than a procedure.
</p>
        <p>
If history would have gone slightly different way, and if yield return, lambda, and
Enumerator API appeared before <code>XmlReader</code>, and <code>XmlWriter</code> then,
we think, both these classes looked differently. Xml source would have been described
with a <code>IEnumerable&lt;XmlEvent&gt;</code> instead of <code>XmlReader</code>,
and <code>XmlWriter</code> must be looked like a function receiving <code>IEnumerable&lt;XmlEvent&gt;</code>.
Implementing <code>XmlReader</code> would have meant a creating a enumerator. Yield
return and Enumerable API would have helped to implement it in a procedural way.
</p>
        <p>
But in our present we have to deal with the fact that <code>DataContractSerializer</code> should
write the data into <code>XmlWriter</code>, so let's assume we have a project
that uses Entity Framework to access the database, and that you have a data class <code>Person</code>,
and data access method <code>GetPeople()</code>:
</p>
        <p>
          <code> [DataContract(Name = "person", Namespace = "http://www.nesterovsky-bros.com")]<br />
public class Person 
<br />
{ 
<br />
[DataMember] public int Id { get; set; } 
<br />
[DataMember] public string FirstName { get; set; } 
<br />
[DataMember] public string LastName { get; set; } 
<br />
[DataMember] public string City { get; set; } 
<br />
[DataMember] public string Title { get; set; } 
<br />
[DataMember] public DateTime BirthDate { get; set; } 
<br />
[DataMember] public int Age { get; set; } 
<br />
} 
<br /><br />
public static IEnumerable&lt;Person&gt; GetPeople() { ... }</code>
        </p>
        <p>
And your goal is to expose result of <code>GetPeople()</code> as <code>XmlReader</code>.
We achieve result with three simple steps:
</p>
        <ol>
          <li>
Define <code>JoinedStream</code> - an input <code>Stream</code> implementation that
reads data from a enumeration of streams (<code>IEnumerable&lt;Stream&gt;</code>).</li>
          <li>
Build xml parts in the form of <code>IEnumerable&lt;Stream&gt;</code>.</li>
          <li>
Combine parts into final xml stream.</li>
        </ol>
        <p>
The code is rather simple, so here we qoute its essential part:
</p>
        <p>
          <code> public static class Extensions<br />
{<br />
public static Stream JoinStreams(this IEnumerable&lt;Stream&gt; streams, bool closeStreams
= true)<br />
{<br />
return new JoinedStream(streams, closeStreams);<br />
}<br /><br />
public static Stream ToXmlStream&lt;T&gt;(<br />
this IEnumerable&lt;T&gt; items, 
<br />
string rootName = null, 
<br />
string rootNamespace = null)<br />
{<br />
return items.ToXmlStreamParts&lt;T&gt;(rootName, rootNamespace).<br />
JoinStreams(false);<br />
}<br /><br />
private static IEnumerable&lt;Stream&gt; ToXmlStreamParts&lt;T&gt;(<br />
this IEnumerable&lt;T&gt; items,<br />
string rootName = null,<br />
string rootNamespace = null)<br />
{<br />
if (rootName == null)<br />
{<br />
rootName = "ArrayOfItems";<br />
}<br /><br />
if (rootNamespace == null)<br />
{<br />
rootNamespace = "";<br />
}<br /><br />
var serializer = new DataContractSerializer(typeof(T));<br />
var stream = new MemoryStream();<br />
var writer = XmlDictionaryWriter.CreateTextWriter(stream);<br /><br />
writer.WriteStartDocument();<br />
writer.WriteStartElement(rootName, rootNamespace);<br />
writer.WriteXmlnsAttribute("s", XmlSchema.Namespace);<br />
writer.WriteXmlnsAttribute("i", XmlSchema.InstanceNamespace);<br /><br />
foreach(var item in items)<br />
{<br />
serializer.WriteObject(writer, item);<br />
writer.WriteString(" ");<br /><br />
writer.Flush();<br />
stream.Position = 0;<br /><br />
yield return stream;<br /><br />
stream.Position = 0;<br />
stream.SetLength(0);<br />
}<br /><br />
writer.WriteEndElement();<br />
writer.WriteEndDocument();<br /><br />
writer.Flush();<br />
stream.Position = 0;<br /><br />
yield return stream;<br />
}<br /><br />
private class JoinedStream: Stream<br />
{<br />
public JoinedStream(IEnumerable&lt;Stream&gt; streams, bool closeStreams = true)<br />
...<br />
}<br />
} </code>
        </p>
        <p>
The use is even more simple:
</p>
        <p>
          <code> // We have a streamed business data.<br />
var people = GetPeople();<br /><br />
// We want to see it as streamed xml data.<br />
using(var stream = people.ToXmlStream("persons", "http://www.nesterovsky-bros.com"))<br />
using(var reader = XmlReader.Create(stream))<br />
{<br />
...<br />
}</code>
        </p>
        <p>
We have packed the sample into the project <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=60b3cb37-5da9-4f28-a35f-38d1ef3cccce&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fStreaming.zip">Streaming.zip</a>.
</p>
        <p>
In the <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=60b3cb37-5da9-4f28-a35f-38d1ef3cccce&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2012%2f07%2f26%2fStreamingXsltTransformationWithForwardXPathNavigator.aspx">next
post</a> we're going to remind about streaming processing in xslt. 
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=60b3cb37-5da9-4f28-a35f-38d1ef3cccce" />
      </body>
      <title>Streaming entity data</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,60b3cb37-5da9-4f28-a35f-38d1ef3cccce.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2012/07/22/StreamingEntityData.aspx</link>
      <pubDate>Sun, 22 Jul 2012 20:38:29 GMT</pubDate>
      <description>  &lt;p&gt;
For some reason neither .NET&amp;#39;s &lt;code&gt;XmlSerializer&lt;/code&gt; nor &lt;code&gt;DataContractSerializer&lt;/code&gt; allow
reading data through an &lt;code&gt;XmlReader&lt;/code&gt;. These APIs work other way round writing
data into an &lt;code&gt;XmlWriter&lt;/code&gt;. To get data through &lt;code&gt;XmlReader&lt;/code&gt; one
needs to write it to some destination like a file or memory stream, and then to read
it using &lt;code&gt;XmlReader&lt;/code&gt;. This complicates streaming design considerably.
&lt;/p&gt;
&lt;p&gt;
In fact the very same happens with other .NET APIs.
&lt;/p&gt;
&lt;p&gt;
We think the reason of why .NET designers preferred &lt;code&gt;XmlWriter&lt;/code&gt; to &lt;code&gt;XmlReader&lt;/code&gt; in
those APIs is that &lt;code&gt;XmlReader&lt;/code&gt;&amp;#39;s implementation is a state machine
like, while &lt;code&gt;XmlWriter&lt;/code&gt;&amp;#39;s implementation looks like a regular procedure.
It&amp;#39;s much harder to &lt;strong&gt;manually&lt;/strong&gt; write and to support a correct state
machine logic than a procedure.
&lt;/p&gt;
&lt;p&gt;
If history would have gone slightly different way, and if yield return, lambda, and
Enumerator API appeared before &lt;code&gt;XmlReader&lt;/code&gt;, and &lt;code&gt;XmlWriter&lt;/code&gt; then,
we think, both these classes looked differently. Xml source would have been described
with a &lt;code&gt;IEnumerable&amp;lt;XmlEvent&amp;gt;&lt;/code&gt; instead of &lt;code&gt;XmlReader&lt;/code&gt;,
and &lt;code&gt;XmlWriter&lt;/code&gt; must be looked like a function receiving &lt;code&gt;IEnumerable&amp;lt;XmlEvent&amp;gt;&lt;/code&gt;.
Implementing &lt;code&gt;XmlReader&lt;/code&gt; would have meant a creating a enumerator. Yield
return and Enumerable API would have helped to implement it in a procedural way.
&lt;/p&gt;
&lt;p&gt;
But in our present we have to deal with the fact that &lt;code&gt;DataContractSerializer&lt;/code&gt; should
write the data into &lt;code&gt;XmlWriter&lt;/code&gt;, so let&amp;#39;s assume we have a project
that uses Entity Framework to access the database, and that you have a data class &lt;code&gt;Person&lt;/code&gt;,
and data access method &lt;code&gt;GetPeople()&lt;/code&gt;:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt; [DataContract(Name = &amp;quot;person&amp;quot;, Namespace = &amp;quot;http://www.nesterovsky-bros.com&amp;quot;)]&lt;br /&gt;
public class Person 
&lt;br /&gt;
{ 
&lt;br /&gt;
[DataMember] public int Id { get; set; } 
&lt;br /&gt;
[DataMember] public string FirstName { get; set; } 
&lt;br /&gt;
[DataMember] public string LastName { get; set; } 
&lt;br /&gt;
[DataMember] public string City { get; set; } 
&lt;br /&gt;
[DataMember] public string Title { get; set; } 
&lt;br /&gt;
[DataMember] public DateTime BirthDate { get; set; } 
&lt;br /&gt;
[DataMember] public int Age { get; set; } 
&lt;br /&gt;
} 
&lt;br /&gt;
&lt;br /&gt;
public static IEnumerable&amp;lt;Person&amp;gt; GetPeople() { ... }&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
And your goal is to expose result of &lt;code&gt;GetPeople()&lt;/code&gt; as &lt;code&gt;XmlReader&lt;/code&gt;.
We achieve result with three simple steps:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Define &lt;code&gt;JoinedStream&lt;/code&gt; - an input &lt;code&gt;Stream&lt;/code&gt; implementation that
reads data from a enumeration of streams (&lt;code&gt;IEnumerable&amp;lt;Stream&amp;gt;&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
Build xml parts in the form of &lt;code&gt;IEnumerable&amp;lt;Stream&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
Combine parts into final xml stream.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
The code is rather simple, so here we qoute its essential part:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt; public static class Extensions&lt;br /&gt;
{&lt;br /&gt;
public static Stream JoinStreams(this IEnumerable&amp;lt;Stream&amp;gt; streams, bool closeStreams
= true)&lt;br /&gt;
{&lt;br /&gt;
return new JoinedStream(streams, closeStreams);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static Stream ToXmlStream&amp;lt;T&amp;gt;(&lt;br /&gt;
this IEnumerable&amp;lt;T&amp;gt; items, 
&lt;br /&gt;
string rootName = null, 
&lt;br /&gt;
string rootNamespace = null)&lt;br /&gt;
{&lt;br /&gt;
return items.ToXmlStreamParts&amp;lt;T&amp;gt;(rootName, rootNamespace).&lt;br /&gt;
JoinStreams(false);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private static IEnumerable&amp;lt;Stream&amp;gt; ToXmlStreamParts&amp;lt;T&amp;gt;(&lt;br /&gt;
this IEnumerable&amp;lt;T&amp;gt; items,&lt;br /&gt;
string rootName = null,&lt;br /&gt;
string rootNamespace = null)&lt;br /&gt;
{&lt;br /&gt;
if (rootName == null)&lt;br /&gt;
{&lt;br /&gt;
rootName = "ArrayOfItems";&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if (rootNamespace == null)&lt;br /&gt;
{&lt;br /&gt;
rootNamespace = "";&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var serializer = new DataContractSerializer(typeof(T));&lt;br /&gt;
var stream = new MemoryStream();&lt;br /&gt;
var writer = XmlDictionaryWriter.CreateTextWriter(stream);&lt;br /&gt;
&lt;br /&gt;
writer.WriteStartDocument();&lt;br /&gt;
writer.WriteStartElement(rootName, rootNamespace);&lt;br /&gt;
writer.WriteXmlnsAttribute("s", XmlSchema.Namespace);&lt;br /&gt;
writer.WriteXmlnsAttribute("i", XmlSchema.InstanceNamespace);&lt;br /&gt;
&lt;br /&gt;
foreach(var item in items)&lt;br /&gt;
{&lt;br /&gt;
serializer.WriteObject(writer, item);&lt;br /&gt;
writer.WriteString(" ");&lt;br /&gt;
&lt;br /&gt;
writer.Flush();&lt;br /&gt;
stream.Position = 0;&lt;br /&gt;
&lt;br /&gt;
yield return stream;&lt;br /&gt;
&lt;br /&gt;
stream.Position = 0;&lt;br /&gt;
stream.SetLength(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
writer.WriteEndElement();&lt;br /&gt;
writer.WriteEndDocument();&lt;br /&gt;
&lt;br /&gt;
writer.Flush();&lt;br /&gt;
stream.Position = 0;&lt;br /&gt;
&lt;br /&gt;
yield return stream;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private class JoinedStream: Stream&lt;br /&gt;
{&lt;br /&gt;
public JoinedStream(IEnumerable&amp;lt;Stream&amp;gt; streams, bool closeStreams = true)&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
The use is even more simple:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt; // We have a streamed business data.&lt;br /&gt;
var people = GetPeople();&lt;br /&gt;
&lt;br /&gt;
// We want to see it as streamed xml data.&lt;br /&gt;
using(var stream = people.ToXmlStream("persons", "http://www.nesterovsky-bros.com"))&lt;br /&gt;
using(var reader = XmlReader.Create(stream))&lt;br /&gt;
{&lt;br /&gt;
...&lt;br /&gt;
}&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
We have packed the sample into the project &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=60b3cb37-5da9-4f28-a35f-38d1ef3cccce&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fStreaming.zip"&gt;Streaming.zip&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
In the &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=60b3cb37-5da9-4f28-a35f-38d1ef3cccce&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2012%2f07%2f26%2fStreamingXsltTransformationWithForwardXPathNavigator.aspx"&gt;next
post&lt;/a&gt; we&amp;#39;re going to remind about streaming processing in xslt. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=60b3cb37-5da9-4f28-a35f-38d1ef3cccce" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,60b3cb37-5da9-4f28-a35f-38d1ef3cccce.aspx</comments>
      <category>.NET</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=558eebcd-e6b3-4238-b8dc-21d0eccaf510</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,558eebcd-e6b3-4238-b8dc-21d0eccaf510.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,558eebcd-e6b3-4238-b8dc-21d0eccaf510.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=558eebcd-e6b3-4238-b8dc-21d0eccaf510</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Some time ago we were taking a part in a project where 95% of all sources are xslt
2.0. It was a great experience for us. 
</p>
        <p>
The interesting part is that we used xslt in areas we would never expect it in early
2000s. It crunched gigabytes of data in offline, while earlier we generally sought
xslt application in a browser or on a server as an engine to render the data.
</p>
        <p>
Web applications (both .NET and java) are in our focus today, and it became hard to
find application for xslt or xquery.
</p>
        <p>
Indeed, client side now have a very strong APIs: jquery, jqueryui, jsview, jqgrid,
kendoui, and so on. These libraries, and today's browsers cover developer's needs
in building managable applications. In contrast, a native support of xslt (at least
v2) does not exist in browsers.
</p>
        <p>
Server side at present is seen as a set of web services. These services support both
xml and json formats, and implement a business logic only. It would be a torture to
try to write such a frontend in xslt/xquery. A server logic itself is often dealing
with a diversity of data sources like databases, files (including xml files) and other.
</p>
        <p>
As for a database (we primarily work with SQL Server 2008 R2), we think that all communication
should go through stored procedures, which implement all data logic. Clearly, this
place is not for xslt. However, those who know sql beyond its basics can confirm that
sql is very similar to xquery. More than that SQL Server (and other databases) integrate
xquery to work with xml data, and we do use it extensively.
</p>
        <p>
Server logic itself uses API like LINQ to manipulate with different data sources.
In fact, we think that one can build a compiler from xquery 3.0 to C# with LINQ. Other
way round compiler would be a whole different story.
</p>
        <p>
The net result is that we see little place for xslt and xquery. Well, after all it's
only a personal perspective on the subject. The similar type of thing has happened
to us with C++. As with xslt/xquery we love C++ very much, and we fond of C++11, but
at present we have no place in our current projects for C++. That's pitty.
</p>
        <p>
P.S. Among other things that play against xslt/xquery is that there is a shortage
of people who know these languages, thus who can support such projects.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=558eebcd-e6b3-4238-b8dc-21d0eccaf510" />
      </body>
      <title>xslt/xquery</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,558eebcd-e6b3-4238-b8dc-21d0eccaf510.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2012/05/08/xsltxquery.aspx</link>
      <pubDate>Tue, 08 May 2012 20:28:51 GMT</pubDate>
      <description>  &lt;p&gt;
Some time ago we were taking a part in a project where 95% of all sources are xslt
2.0. It was a great experience for us. 
&lt;/p&gt;
&lt;p&gt;
The interesting part is that we used xslt in areas we would never expect it in early
2000s. It crunched gigabytes of data in offline, while earlier we generally sought
xslt application in a browser or on a server as an engine to render the data.
&lt;/p&gt;
&lt;p&gt;
Web applications (both .NET and java) are in our focus today, and it became hard to
find application for xslt or xquery.
&lt;/p&gt;
&lt;p&gt;
Indeed, client side now have a very strong APIs: jquery, jqueryui, jsview, jqgrid,
kendoui, and so on. These libraries, and today's browsers cover developer's needs
in building managable applications. In contrast, a native support of xslt (at least
v2) does not exist in browsers.
&lt;/p&gt;
&lt;p&gt;
Server side at present is seen as a set of web services. These services support both
xml and json formats, and implement a business logic only. It would be a torture to
try to write such a frontend in xslt/xquery. A server logic itself is often dealing
with a diversity of data sources like databases, files (including xml files) and other.
&lt;/p&gt;
&lt;p&gt;
As for a database (we primarily work with SQL Server 2008 R2), we think that all communication
should go through stored procedures, which implement all data logic. Clearly, this
place is not for xslt. However, those who know sql beyond its basics can confirm that
sql is very similar to xquery. More than that SQL Server (and other databases) integrate
xquery to work with xml data, and we do use it extensively.
&lt;/p&gt;
&lt;p&gt;
Server logic itself uses API like LINQ to manipulate with different data sources.
In fact, we think that one can build a compiler from xquery 3.0 to C# with LINQ. Other
way round compiler would be a whole different story.
&lt;/p&gt;
&lt;p&gt;
The net result is that we see little place for xslt and xquery. Well, after all it's
only a personal perspective on the subject. The similar type of thing has happened
to us with C++. As with xslt/xquery we love C++ very much, and we fond of C++11, but
at present we have no place in our current projects for C++. That's pitty.
&lt;/p&gt;
&lt;p&gt;
P.S. Among other things that play against xslt/xquery is that there is a shortage
of people who know these languages, thus who can support such projects.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=558eebcd-e6b3-4238-b8dc-21d0eccaf510" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,558eebcd-e6b3-4238-b8dc-21d0eccaf510.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=19c9c7e3-4b24-4407-806a-b118460873e3</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,19c9c7e3-4b24-4407-806a-b118460873e3.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,19c9c7e3-4b24-4407-806a-b118460873e3.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=19c9c7e3-4b24-4407-806a-b118460873e3</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This time we <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=19c9c7e3-4b24-4407-806a-b118460873e3&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip">update
csharpxom</a> to adjust it to C# 4.5. Additions are<a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=19c9c7e3-4b24-4407-806a-b118460873e3&amp;url=http%3a%2f%2fmsdn.microsoft.com%2fen-us%2flibrary%2fhh156513(v%3dvs.110).aspx"><code>async</code> modifier</a> and <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=19c9c7e3-4b24-4407-806a-b118460873e3&amp;url=http%3a%2f%2fmsdn.microsoft.com%2fen-us%2flibrary%2fhh156528(v%3dvs.110).aspx"><code>await</code> operator</a>.
</p>
        <p>
They are used to simplify asynchronous programming.
</p>
        <p>
The following example from the msdn:
</p>
        <p style="padding-left: 1em">
          <code>private async Task&lt;byte[]&gt; GetURLContentsAsync(string url)<br />
{<br />
var content = new MemoryStream();<br />
var request = (HttpWebRequest)WebRequest.Create(url);<br /><br />
using(var response = await request.GetResponseAsync())<br />
using(var responseStream = response.GetResponseStream())<br />
{<br />
await responseStream.CopyToAsync(content);<br />
}<br /><br />
return content.ToArray();<br />
}</code>
        </p>
        <p>
looks like this in csharpxom:
</p>
        <p style="padding-left: 1em">
          <code>&lt;method name="GetURLContentsAsync" access="private" <span style="font-weight: bold">async="true"</span>&gt;<br />
&lt;returns&gt;<br />
&lt;type name="Task" namespace="System.Threading.Tasks"&gt;<br />
&lt;type-arguments&gt;<br />
&lt;type name="byte" rank="1"/&gt;<br />
&lt;/type-arguments&gt;<br />
&lt;/type&gt;<br />
&lt;/returns&gt;<br />
&lt;parameters&gt;<br />
&lt;parameter name="url"&gt;<br />
&lt;type name="string"/&gt;<br />
&lt;/parameter&gt;<br />
&lt;/parameters&gt;<br />
&lt;block&gt;<br />
&lt;var name="content"&gt;<br />
&lt;initialize&gt;<br />
&lt;new-object&gt;<br />
&lt;type name="MemoryStream" namespace="System.IO"/&gt;<br />
&lt;/new-object&gt;<br />
&lt;/initialize&gt;<br />
&lt;/var&gt;<br />
&lt;var name="request"&gt;<br />
&lt;initialize&gt;<br />
&lt;cast&gt;<br />
&lt;invoke&gt;<br />
&lt;static-method-ref name="Create"&gt;<br />
&lt;type name="WebRequest" namespace="System.Net"/&gt;<br />
&lt;/static-method-ref&gt;<br />
&lt;arguments&gt;<br />
&lt;var-ref name="url"/&gt;<br />
&lt;/arguments&gt;<br />
&lt;/invoke&gt;<br />
&lt;type name="HttpWebRequest" namespace="System.Net"/&gt;<br />
&lt;/cast&gt;<br />
&lt;/initialize&gt;<br />
&lt;/var&gt;<br /><br />
&lt;using&gt;<br />
&lt;resource&gt;<br />
&lt;var name="response"&gt;<br />
&lt;initialize&gt;<br /><span style="font-weight: bold">&lt;await&gt;</span><br />
&lt;invoke&gt;<br />
&lt;method-ref name="GetResponseAsync"&gt;<br />
&lt;var-ref name="request"/&gt;<br />
&lt;/method-ref&gt;<br />
&lt;/invoke&gt;<br /><span style="font-weight: bold">&lt;/await&gt;</span><br />
&lt;/initialize&gt;<br />
&lt;/var&gt;<br />
&lt;/resource&gt;<br />
&lt;using&gt;<br />
&lt;resource&gt;<br />
&lt;var name="responseStream"&gt;<br />
&lt;initialize&gt;<br />
&lt;invoke&gt;<br />
&lt;method-ref name="GetResponseStream"&gt;<br />
&lt;var-ref name="response"/&gt;<br />
&lt;/method-ref&gt;<br />
&lt;/invoke&gt;<br />
&lt;/initialize&gt;<br />
&lt;/var&gt;<br />
&lt;/resource&gt;<br />
&lt;expression&gt;<br /><span style="font-weight: bold">&lt;await&gt;</span><br />
&lt;invoke&gt;<br />
&lt;method-ref name="CopyToAsync"&gt;<br />
&lt;var-ref name="responseStream"/&gt;<br />
&lt;/method-ref&gt;<br />
&lt;arguments&gt;<br />
&lt;var-ref name="content"/&gt;<br />
&lt;/arguments&gt;<br />
&lt;/invoke&gt;<br /><span style="font-weight: bold">&lt;/await&gt;</span><br />
&lt;/expression&gt;<br />
&lt;/using&gt;<br />
&lt;/using&gt;<br /><br />
&lt;return&gt;<br />
&lt;invoke&gt;<br />
&lt;method-ref name="ToArray"&gt;<br />
&lt;var-ref name="content"/&gt;<br />
&lt;/method-ref&gt;<br />
&lt;/invoke&gt;<br />
&lt;/return&gt;<br />
&lt;/block&gt;<br />
&lt;/method&gt;</code>
        </p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=19c9c7e3-4b24-4407-806a-b118460873e3" />
      </body>
      <title>Languages XOM update</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,19c9c7e3-4b24-4407-806a-b118460873e3.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2012/03/23/LanguagesXOMUpdate.aspx</link>
      <pubDate>Fri, 23 Mar 2012 00:07:35 GMT</pubDate>
      <description>  &lt;p&gt;
This time we &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=19c9c7e3-4b24-4407-806a-b118460873e3&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip"&gt;update
csharpxom&lt;/a&gt; to adjust it to C# 4.5. Additions are&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=19c9c7e3-4b24-4407-806a-b118460873e3&amp;amp;url=http%3a%2f%2fmsdn.microsoft.com%2fen-us%2flibrary%2fhh156513(v%3dvs.110).aspx"&gt; &lt;code&gt;async&lt;/code&gt; modifier&lt;/a&gt; and &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=19c9c7e3-4b24-4407-806a-b118460873e3&amp;amp;url=http%3a%2f%2fmsdn.microsoft.com%2fen-us%2flibrary%2fhh156528(v%3dvs.110).aspx"&gt; &lt;code&gt;await&lt;/code&gt; operator&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
They are used to simplify asynchronous programming.
&lt;/p&gt;
&lt;p&gt;
The following example from the msdn:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;private async Task&amp;lt;byte[]&amp;gt; GetURLContentsAsync(string url)&lt;br /&gt;
{&lt;br /&gt;
var content = new MemoryStream();&lt;br /&gt;
var request = (HttpWebRequest)WebRequest.Create(url);&lt;br /&gt;
&lt;br /&gt;
using(var response = await request.GetResponseAsync())&lt;br /&gt;
using(var responseStream = response.GetResponseStream())&lt;br /&gt;
{&lt;br /&gt;
await responseStream.CopyToAsync(content);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return content.ToArray();&lt;br /&gt;
}&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
looks like this in csharpxom:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&amp;lt;method name="GetURLContentsAsync" access="private" &lt;span style="font-weight: bold"&gt;async="true"&lt;/span&gt;&amp;gt;&lt;br /&gt;
&amp;lt;returns&amp;gt;&lt;br /&gt;
&amp;lt;type name="Task" namespace="System.Threading.Tasks"&amp;gt;&lt;br /&gt;
&amp;lt;type-arguments&amp;gt;&lt;br /&gt;
&amp;lt;type name="byte" rank="1"/&amp;gt;&lt;br /&gt;
&amp;lt;/type-arguments&amp;gt;&lt;br /&gt;
&amp;lt;/type&amp;gt;&lt;br /&gt;
&amp;lt;/returns&amp;gt;&lt;br /&gt;
&amp;lt;parameters&amp;gt;&lt;br /&gt;
&amp;lt;parameter name="url"&amp;gt;&lt;br /&gt;
&amp;lt;type name="string"/&amp;gt;&lt;br /&gt;
&amp;lt;/parameter&amp;gt;&lt;br /&gt;
&amp;lt;/parameters&amp;gt;&lt;br /&gt;
&amp;lt;block&amp;gt;&lt;br /&gt;
&amp;lt;var name="content"&amp;gt;&lt;br /&gt;
&amp;lt;initialize&amp;gt;&lt;br /&gt;
&amp;lt;new-object&amp;gt;&lt;br /&gt;
&amp;lt;type name="MemoryStream" namespace="System.IO"/&amp;gt;&lt;br /&gt;
&amp;lt;/new-object&amp;gt;&lt;br /&gt;
&amp;lt;/initialize&amp;gt;&lt;br /&gt;
&amp;lt;/var&amp;gt;&lt;br /&gt;
&amp;lt;var name="request"&amp;gt;&lt;br /&gt;
&amp;lt;initialize&amp;gt;&lt;br /&gt;
&amp;lt;cast&amp;gt;&lt;br /&gt;
&amp;lt;invoke&amp;gt;&lt;br /&gt;
&amp;lt;static-method-ref name="Create"&amp;gt;&lt;br /&gt;
&amp;lt;type name="WebRequest" namespace="System.Net"/&amp;gt;&lt;br /&gt;
&amp;lt;/static-method-ref&amp;gt;&lt;br /&gt;
&amp;lt;arguments&amp;gt;&lt;br /&gt;
&amp;lt;var-ref name="url"/&amp;gt;&lt;br /&gt;
&amp;lt;/arguments&amp;gt;&lt;br /&gt;
&amp;lt;/invoke&amp;gt;&lt;br /&gt;
&amp;lt;type name="HttpWebRequest" namespace="System.Net"/&amp;gt;&lt;br /&gt;
&amp;lt;/cast&amp;gt;&lt;br /&gt;
&amp;lt;/initialize&amp;gt;&lt;br /&gt;
&amp;lt;/var&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;using&amp;gt;&lt;br /&gt;
&amp;lt;resource&amp;gt;&lt;br /&gt;
&amp;lt;var name="response"&amp;gt;&lt;br /&gt;
&amp;lt;initialize&amp;gt;&lt;br /&gt;
&lt;span style="font-weight: bold"&gt;&amp;lt;await&amp;gt;&lt;/span&gt;
&lt;br /&gt;
&amp;lt;invoke&amp;gt;&lt;br /&gt;
&amp;lt;method-ref name="GetResponseAsync"&amp;gt;&lt;br /&gt;
&amp;lt;var-ref name="request"/&amp;gt;&lt;br /&gt;
&amp;lt;/method-ref&amp;gt;&lt;br /&gt;
&amp;lt;/invoke&amp;gt;&lt;br /&gt;
&lt;span style="font-weight: bold"&gt;&amp;lt;/await&amp;gt;&lt;/span&gt;
&lt;br /&gt;
&amp;lt;/initialize&amp;gt;&lt;br /&gt;
&amp;lt;/var&amp;gt;&lt;br /&gt;
&amp;lt;/resource&amp;gt;&lt;br /&gt;
&amp;lt;using&amp;gt;&lt;br /&gt;
&amp;lt;resource&amp;gt;&lt;br /&gt;
&amp;lt;var name="responseStream"&amp;gt;&lt;br /&gt;
&amp;lt;initialize&amp;gt;&lt;br /&gt;
&amp;lt;invoke&amp;gt;&lt;br /&gt;
&amp;lt;method-ref name="GetResponseStream"&amp;gt;&lt;br /&gt;
&amp;lt;var-ref name="response"/&amp;gt;&lt;br /&gt;
&amp;lt;/method-ref&amp;gt;&lt;br /&gt;
&amp;lt;/invoke&amp;gt;&lt;br /&gt;
&amp;lt;/initialize&amp;gt;&lt;br /&gt;
&amp;lt;/var&amp;gt;&lt;br /&gt;
&amp;lt;/resource&amp;gt;&lt;br /&gt;
&amp;lt;expression&amp;gt;&lt;br /&gt;
&lt;span style="font-weight: bold"&gt;&amp;lt;await&amp;gt;&lt;/span&gt;
&lt;br /&gt;
&amp;lt;invoke&amp;gt;&lt;br /&gt;
&amp;lt;method-ref name="CopyToAsync"&amp;gt;&lt;br /&gt;
&amp;lt;var-ref name="responseStream"/&amp;gt;&lt;br /&gt;
&amp;lt;/method-ref&amp;gt;&lt;br /&gt;
&amp;lt;arguments&amp;gt;&lt;br /&gt;
&amp;lt;var-ref name="content"/&amp;gt;&lt;br /&gt;
&amp;lt;/arguments&amp;gt;&lt;br /&gt;
&amp;lt;/invoke&amp;gt;&lt;br /&gt;
&lt;span style="font-weight: bold"&gt;&amp;lt;/await&amp;gt;&lt;/span&gt;
&lt;br /&gt;
&amp;lt;/expression&amp;gt;&lt;br /&gt;
&amp;lt;/using&amp;gt;&lt;br /&gt;
&amp;lt;/using&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;return&amp;gt;&lt;br /&gt;
&amp;lt;invoke&amp;gt;&lt;br /&gt;
&amp;lt;method-ref name="ToArray"&amp;gt;&lt;br /&gt;
&amp;lt;var-ref name="content"/&amp;gt;&lt;br /&gt;
&amp;lt;/method-ref&amp;gt;&lt;br /&gt;
&amp;lt;/invoke&amp;gt;&lt;br /&gt;
&amp;lt;/return&amp;gt;&lt;br /&gt;
&amp;lt;/block&amp;gt;&lt;br /&gt;
&amp;lt;/method&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=19c9c7e3-4b24-4407-806a-b118460873e3" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,19c9c7e3-4b24-4407-806a-b118460873e3.aspx</comments>
      <category>.NET</category>
      <category>Announce</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=08d97135-32ca-4586-bdf4-410ef43f8ebe</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,08d97135-32ca-4586-bdf4-410ef43f8ebe.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,08d97135-32ca-4586-bdf4-410ef43f8ebe.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=08d97135-32ca-4586-bdf4-410ef43f8ebe</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p style="padding-left: 1em; font-style: italic">
          <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=08d97135-32ca-4586-bdf4-410ef43f8ebe&amp;url=http%3a%2f%2ftwitter.com%2f%23!%2fmichaelhkay%2fstatuses%2f145259939055673344">@michaelhkay
Saxon 9.4 is out.</a>
        </p>
        <p>
But why author does not state that HE version is still xslt/xpath 2.0, as neither
xslt maps, nor function items are supported.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=08d97135-32ca-4586-bdf4-410ef43f8ebe" />
      </body>
      <title>Saxon 9.4 is out</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,08d97135-32ca-4586-bdf4-410ef43f8ebe.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2011/12/10/Saxon94IsOut.aspx</link>
      <pubDate>Sat, 10 Dec 2011 12:16:28 GMT</pubDate>
      <description>&lt;p style="padding-left: 1em; font-style: italic"&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=08d97135-32ca-4586-bdf4-410ef43f8ebe&amp;amp;url=http%3a%2f%2ftwitter.com%2f%23!%2fmichaelhkay%2fstatuses%2f145259939055673344"&gt;@michaelhkay
Saxon 9.4 is out.&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
But why author does not state that HE version is still xslt/xpath 2.0, as neither
xslt maps, nor function items are supported.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=08d97135-32ca-4586-bdf4-410ef43f8ebe" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,08d97135-32ca-4586-bdf4-410ef43f8ebe.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=ad1c5ce2-4806-4de7-8c58-6af54cb9df06</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,ad1c5ce2-4806-4de7-8c58-6af54cb9df06.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,ad1c5ce2-4806-4de7-8c58-6af54cb9df06.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=ad1c5ce2-4806-4de7-8c58-6af54cb9df06</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It has happened so, that we have never worked with jQuery, however were aware of it.
</p>
        <p>
In early 2000 we have developed a web application that contained rich javascript APIs,
including UI components. Later, we were actively practicing in ASP.NET, and later
in JSF.
</p>
        <p>
At present, looking at jQuery more closely we regret that we have failed to start
using it earlier.
</p>
        <p>
Separation of business logic and presentation is remarkable when one uses JSON web
services. In fact server part can be seen as a set of web services representing a
business logic and a set of resources: html, styles, scripts, others. Nor ASP.NET
or JSF approach such a consistent separation.
</p>
        <p>
The only trouble, in our opinion, is that jQuery has no standard data binding: a way
to bind JSON data to (and from) html controls. The technique that will probably be
standardized is called <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=ad1c5ce2-4806-4de7-8c58-6af54cb9df06&amp;url=https%3a%2f%2fgithub.com%2fBorisMoore%2fjsviews">jQuery
Templates or JsViews </a> .
</p>
        <p>
Unfortunatelly after reading about this <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=ad1c5ce2-4806-4de7-8c58-6af54cb9df06&amp;url=http%3a%2f%2fwiki.jqueryui.com%2fw%2fpage%2f37898666%2fTemplate">binding
API</a>, and being in love with Xslt and XQuery we just want to cry. We don't know
what would be the best solution for the task, but what we see looks uncomfortable
to us.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=ad1c5ce2-4806-4de7-8c58-6af54cb9df06" />
      </body>
      <title>jQuery</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,ad1c5ce2-4806-4de7-8c58-6af54cb9df06.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2011/10/28/jQuery.aspx</link>
      <pubDate>Fri, 28 Oct 2011 22:59:23 GMT</pubDate>
      <description>&lt;p&gt;
It has happened so, that we have never worked with jQuery, however were aware of it.
&lt;/p&gt;
&lt;p&gt;
In early 2000 we have developed a web application that contained rich javascript APIs,
including UI components. Later, we were actively practicing in ASP.NET, and later
in JSF.
&lt;/p&gt;
&lt;p&gt;
At present, looking at jQuery more closely we regret that we have failed to start
using it earlier.
&lt;/p&gt;
&lt;p&gt;
Separation of business logic and presentation is remarkable when one uses JSON web
services. In fact server part can be seen as a set of web services representing a
business logic and a set of resources: html, styles, scripts, others. Nor ASP.NET
or JSF approach such a consistent separation.
&lt;/p&gt;
&lt;p&gt;
The only trouble, in our opinion, is that jQuery has no standard data binding: a way
to bind JSON data to (and from) html controls. The technique that will probably be
standardized is called &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=ad1c5ce2-4806-4de7-8c58-6af54cb9df06&amp;amp;url=https%3a%2f%2fgithub.com%2fBorisMoore%2fjsviews"&gt;jQuery
Templates or JsViews &lt;/a&gt; .
&lt;/p&gt;
&lt;p&gt;
Unfortunatelly after reading about this &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=ad1c5ce2-4806-4de7-8c58-6af54cb9df06&amp;amp;url=http%3a%2f%2fwiki.jqueryui.com%2fw%2fpage%2f37898666%2fTemplate"&gt;binding
API&lt;/a&gt;, and being in love with Xslt and XQuery we just want to cry. We don't know
what would be the best solution for the task, but what we see looks uncomfortable
to us.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=ad1c5ce2-4806-4de7-8c58-6af54cb9df06" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,ad1c5ce2-4806-4de7-8c58-6af54cb9df06.aspx</comments>
      <category>ASP.NET</category>
      <category>JSF and Facelets</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=9c7823a7-6ac4-41ca-a75a-de10204879cd</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,9c7823a7-6ac4-41ca-a75a-de10204879cd.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,9c7823a7-6ac4-41ca-a75a-de10204879cd.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=9c7823a7-6ac4-41ca-a75a-de10204879cd</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A couple of weeks ago, we have suggested to introduce a enumerator function into the
XPath (see <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=9c7823a7-6ac4-41ca-a75a-de10204879cd&amp;url=http%3a%2f%2fwww.w3.org%2fBugs%2fPublic%2fshow_bug.cgi%3fid%3d14152"> [F+O30]
A enumerator function</a>):
</p>
        <p style="font-style: italic; padding-left: 1em">
I would like the WG to consider an addition of a function that turns a sequence into
a enumeration of values.<br /><br />
Consider a function like this:  fn:enumerator($items as item()*) as function()
as item()<span style="font-weight: bold">?</span>;<br /><br />
alternatively, signature could be:<br /><br />
 fn:enumerator($items as function() as item()*) as function() as item()<span style="font-weight: bold">?</span>;<br /><br />
This function receives a sequence, and returns a function item, which upon N's
call shall return N's element of the original sequence. This way, a sequence of
items is turned into a function providing a enumeration of items of the sequence. 
<br /><br />
As an example consider two functions:<br /><br />
a) t:rand($seed as xs:double) as xs:double* - a function producing a random number
sequence;<br />
b) t:work($input as element()) as element() - a function that generates output from
it's input, and that needs random numbers in the course of the execution. 
<br /><br />
t:work() may contain a code like this:<br />
  let $rand := fn:enumerator(t:rand($seed)),<br /><br />
and later it can call $rand() to get a random numbers. 
<br /><br />
Enumerators will help to compose algorithms where one algorithm communicate with other
independant algorithms, thus making code simpler. The most obvious class of enumerators
are generators: ordered numbers, unique identifiers, random numbers. 
<br /><br />
Technically, <span style="font-weight: bold">function returned from</span> fn:enumerator()
is nondetermenistic, but its "side effect" is similar to a "side effect"
of a function generate-id() from a newly created node (see <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=9c7823a7-6ac4-41ca-a75a-de10204879cd&amp;url=http%3a%2f%2fwww.w3.org%2fBugs%2fPublic%2fshow_bug.cgi%3fid%3d13747" title="RESOLVED LATER - [XPath 3.0] Determinism of expressions returning constructed nodes">bug
#13747</a>, and <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=9c7823a7-6ac4-41ca-a75a-de10204879cd&amp;url=http%3a%2f%2fwww.w3.org%2fBugs%2fPublic%2fshow_bug.cgi%3fid%3d13494" title="NEW - Node uniqueness returned from XSLT function.">bug
#13494</a>). 
</p>
        <p>
The idea is inspired by a generator function, which returns a new value upon each
call. 
</p>
        <p>
Such function can be seen as a stateful object. But our goal is to look at it in a
more functional way. So, we look at the algorithm as a function that produces a sequence
of output, which is pure functional; and an enumerator that allows to iterate over
algorithm's output.
</p>
        <p>
This way, we see the function that implements an algorithm and the function that uses
it can be seen as two thread of functional programs that use messaging to communicate
to each other.
</p>
        <p>
Honestly, we doubt that WG will accept it, but it's interesting to watch the discussion.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=9c7823a7-6ac4-41ca-a75a-de10204879cd" />
      </body>
      <title>An XPath enumerator function</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,9c7823a7-6ac4-41ca-a75a-de10204879cd.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2011/09/29/AnXPathEnumeratorFunction.aspx</link>
      <pubDate>Thu, 29 Sep 2011 11:56:05 GMT</pubDate>
      <description>&lt;p&gt;
A couple of weeks ago, we have suggested to introduce a enumerator function into the
XPath (see &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=9c7823a7-6ac4-41ca-a75a-de10204879cd&amp;amp;url=http%3a%2f%2fwww.w3.org%2fBugs%2fPublic%2fshow_bug.cgi%3fid%3d14152"&gt; [F+O30]
A enumerator function&lt;/a&gt;):
&lt;/p&gt;
&lt;p style="font-style: italic; padding-left: 1em"&gt;
I would like the WG to consider an addition of a function that turns a sequence into
a enumeration of values.&lt;br /&gt;
&lt;br /&gt;
Consider a function like this: &amp;nbsp;fn:enumerator($items as item()*) as function()
as item()&lt;span style="font-weight: bold"&gt;?&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
alternatively, signature could be:&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;fn:enumerator($items as function() as item()*) as function() as item()&lt;span style="font-weight: bold"&gt;?&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
This function receives a sequence, and returns a function item, which upon N&amp;#39;s
call shall return N&amp;#39;s element of the original sequence. This way, a sequence of
items is turned into a function providing a enumeration of items of the sequence. 
&lt;br /&gt;
&lt;br /&gt;
As an example consider two functions:&lt;br /&gt;
&lt;br /&gt;
a) t:rand($seed as xs:double) as xs:double* - a function producing a random number
sequence;&lt;br /&gt;
b) t:work($input as element()) as element() - a function that generates output from
it&amp;#39;s input, and that needs random numbers in the course of the execution. 
&lt;br /&gt;
&lt;br /&gt;
t:work() may contain a code like this:&lt;br /&gt;
&amp;nbsp; let $rand := fn:enumerator(t:rand($seed)),&lt;br /&gt;
&lt;br /&gt;
and later it can call $rand() to get a random numbers. 
&lt;br /&gt;
&lt;br /&gt;
Enumerators will help to compose algorithms where one algorithm communicate with other
independant algorithms, thus making code simpler. The most obvious class of enumerators
are generators: ordered numbers, unique identifiers, random numbers. 
&lt;br /&gt;
&lt;br /&gt;
Technically, &lt;span style="font-weight: bold"&gt;function returned from&lt;/span&gt; fn:enumerator()
is nondetermenistic, but its &amp;quot;side effect&amp;quot; is similar to a &amp;quot;side effect&amp;quot;
of a function generate-id() from a newly created node (see &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=9c7823a7-6ac4-41ca-a75a-de10204879cd&amp;amp;url=http%3a%2f%2fwww.w3.org%2fBugs%2fPublic%2fshow_bug.cgi%3fid%3d13747" title="RESOLVED LATER - [XPath 3.0] Determinism of expressions returning constructed nodes"&gt;bug
#13747&lt;/a&gt;, and &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=9c7823a7-6ac4-41ca-a75a-de10204879cd&amp;amp;url=http%3a%2f%2fwww.w3.org%2fBugs%2fPublic%2fshow_bug.cgi%3fid%3d13494" title="NEW - Node uniqueness returned from XSLT function."&gt;bug
#13494&lt;/a&gt;). 
&lt;/p&gt;
&lt;p&gt;
The idea is inspired by a generator function, which returns a new value upon each
call. 
&lt;/p&gt;
&lt;p&gt;
Such function can be seen as a stateful object. But our goal is to look at it in a
more functional way. So, we look at the algorithm as a function that produces a sequence
of output, which is pure functional; and an enumerator that allows to iterate over
algorithm&amp;#39;s output.
&lt;/p&gt;
&lt;p&gt;
This way, we see the function that implements an algorithm and the function that uses
it can be seen as two thread of functional programs that use messaging to communicate
to each other.
&lt;/p&gt;
&lt;p&gt;
Honestly, we doubt that WG will accept it, but it&amp;#39;s interesting to watch the discussion.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=9c7823a7-6ac4-41ca-a75a-de10204879cd" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,9c7823a7-6ac4-41ca-a75a-de10204879cd.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=d0be8e77-04d9-47a0-840e-d62b1936b3ac</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,d0be8e77-04d9-47a0-840e-d62b1936b3ac.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,d0be8e77-04d9-47a0-840e-d62b1936b3ac.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=d0be8e77-04d9-47a0-840e-d62b1936b3ac</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
More than month has passed since we have reported a problem to the saxon forum (see <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=d0be8e77-04d9-47a0-840e-d62b1936b3ac&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2011%2f07%2f27%2fSaxonOptimizerBug.aspx"> Saxon
optimizer bug</a> and <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=d0be8e77-04d9-47a0-840e-d62b1936b3ac&amp;url=http%3a%2f%2fsourceforge.net%2fprojects%2fsaxon%2fforums%2fforum%2f94027%2ftopic%2f4621860"> Saxon
9.2 generate-id() bug)</a>. 
</p>
        <p>
The essence of the problem is that we have constructed argumentless function to return
a unique identifiers each time function is called. To achieve the effect we have created
a temporary node and returned its <code>generate-id()</code> value.
</p>
        <p>
Such a function is nondetermenistic, as we cannot state that its result depends on
arguments only. This means that engine's optimizer is not free to reorder calls to
such a function. That's what happens in Saxon 9.2, and Saxon 9.3 where engine
elevates function call out of cycle thus producing invalid results.
</p>
        <p>
Michael Kay, the author of the Saxon engine, argued that this is "a gray area
of the xslt spec":
</p>
        <p style="padding-left: 1em; font-style: italic">
If the spec were stricter about defining exactly when you can rely on identity-dependent
operations then I would be obliged to follow it, but I think it's probably deliberate
that it currently allows implementations some latitude, effectively signalling to
users that they should avoid depending on this aspect of the behaviour. 
</p>
        <p>
He adviced to raise a bug in the w3c bugzilla to resolve the issue. In the end two
related bugs have been raised:
</p>
        <ul>
          <li>
            <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=d0be8e77-04d9-47a0-840e-d62b1936b3ac&amp;url=http%3a%2f%2fwww.w3.org%2fBugs%2fPublic%2fshow_bug.cgi%3fid%3d13494">Bug
13494</a> - Node uniqueness returned from XSLT function;</li>
          <li>
            <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=d0be8e77-04d9-47a0-840e-d62b1936b3ac&amp;url=http%3a%2f%2fwww.w3.org%2fBugs%2fPublic%2fshow_bug.cgi%3fid%3d13747">Bug
13747</a> - [XPath 3.0] Determinism of expressions returning constructed nodes.</li>
        </ul>
        <p>
Yesterday, the WG has resolved the issue:
</p>
        <p style="padding: 1em; font-style: italic">
The Working Group agreed that default behavior should continue to require these nodes
to be constructed with unique IDs. We believe that this is the kind of thing implementations
can do with annotations or declaration options, and it would be best to get implementation
experience with this before standardizing.
</p>
        <p>
This means that the technique we used to generate unique identifiers is correct and
the behaviour is well defined.
</p>
        <p>
The only problem is to wait when Saxon will fix its behaviour accordingly.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=d0be8e77-04d9-47a0-840e-d62b1936b3ac" />
      </body>
      <title>Resolution of the Saxon optimizer bug</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,d0be8e77-04d9-47a0-840e-d62b1936b3ac.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2011/09/14/ResolutionOfTheSaxonOptimizerBug.aspx</link>
      <pubDate>Wed, 14 Sep 2011 05:54:56 GMT</pubDate>
      <description>&lt;p&gt;
More than month has passed since we have reported a problem to the saxon forum (see &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=d0be8e77-04d9-47a0-840e-d62b1936b3ac&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2011%2f07%2f27%2fSaxonOptimizerBug.aspx"&gt; Saxon
optimizer bug&lt;/a&gt; and &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=d0be8e77-04d9-47a0-840e-d62b1936b3ac&amp;amp;url=http%3a%2f%2fsourceforge.net%2fprojects%2fsaxon%2fforums%2fforum%2f94027%2ftopic%2f4621860"&gt; Saxon
9.2 generate-id() bug)&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
The essence of the problem is that we have constructed argumentless function to return
a unique identifiers each time function is called. To achieve the effect we have created
a temporary node and returned its &lt;code&gt;generate-id()&lt;/code&gt; value.
&lt;/p&gt;
&lt;p&gt;
Such a function is nondetermenistic, as we cannot state that its result depends on
arguments only. This means that engine's optimizer is not free to reorder calls to
such a function. That&amp;#39;s what happens in Saxon 9.2, and Saxon 9.3 where engine
elevates function call out of cycle thus producing invalid results.
&lt;/p&gt;
&lt;p&gt;
Michael Kay, the author of the Saxon engine, argued that this is &amp;quot;a gray area
of the xslt spec&amp;quot;:
&lt;/p&gt;
&lt;p style="padding-left: 1em; font-style: italic"&gt;
If the spec were stricter about defining exactly when you can rely on identity-dependent
operations then I would be obliged to follow it, but I think it&amp;#39;s probably deliberate
that it currently allows implementations some latitude, effectively signalling to
users that they should avoid depending on this aspect of the behaviour. 
&lt;/p&gt;
&lt;p&gt;
He adviced to raise a bug in the w3c bugzilla to resolve the issue. In the end two
related bugs have been raised:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=d0be8e77-04d9-47a0-840e-d62b1936b3ac&amp;amp;url=http%3a%2f%2fwww.w3.org%2fBugs%2fPublic%2fshow_bug.cgi%3fid%3d13494"&gt;Bug
13494&lt;/a&gt; - Node uniqueness returned from XSLT function;&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=d0be8e77-04d9-47a0-840e-d62b1936b3ac&amp;amp;url=http%3a%2f%2fwww.w3.org%2fBugs%2fPublic%2fshow_bug.cgi%3fid%3d13747"&gt;Bug
13747&lt;/a&gt; - [XPath 3.0] Determinism of expressions returning constructed nodes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Yesterday, the WG has resolved the issue:
&lt;/p&gt;
&lt;p style="padding: 1em; font-style: italic"&gt;
The Working Group agreed that default behavior should continue to require these nodes
to be constructed with unique IDs. We believe that this is the kind of thing implementations
can do with annotations or declaration options, and it would be best to get implementation
experience with this before standardizing.
&lt;/p&gt;
&lt;p&gt;
This means that the technique we used to generate unique identifiers is correct and
the behaviour is well defined.
&lt;/p&gt;
&lt;p&gt;
The only problem is to wait when Saxon will fix its behaviour accordingly.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=d0be8e77-04d9-47a0-840e-d62b1936b3ac" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,d0be8e77-04d9-47a0-840e-d62b1936b3ac.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=a2345b18-13e4-4f60-b798-4b28587a18cb</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,a2345b18-13e4-4f60-b798-4b28587a18cb.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,a2345b18-13e4-4f60-b798-4b28587a18cb.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=a2345b18-13e4-4f60-b798-4b28587a18cb</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Recently one of users of <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a2345b18-13e4-4f60-b798-4b28587a18cb&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2011%2f01%2f24%2fYieldReturnFeatureInJava.aspx">java
yield return annotation</a> has kindly informed us about some problem that happened
in his environment (see <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a2345b18-13e4-4f60-b798-4b28587a18cb&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2011%2f02%2f05%2fJavasYieldReturnAnnotationUpdate.aspx"> Java's
@Yield return annotation update</a>).
</p>
        <p>
Incidentally we have never noticed the problem earlier. Along with this issue we have
found that eclipse compiler has changed in the Indigo in a way that we had to recompile
the source. Well, that's a price you have to pay when you access internal API.
</p>
        <p>
Updated sources can be found at <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a2345b18-13e4-4f60-b798-4b28587a18cb&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fjava%2fYield.zip">Yield.zip</a>,
and compiled jars at <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a2345b18-13e4-4f60-b798-4b28587a18cb&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fjava%2fYield.jar">Yield.jar</a> (pre-Indigo),
and <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a2345b18-13e4-4f60-b798-4b28587a18cb&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fjava%2fYield.3.7.jar"> Yield.3.7.jar</a> (Indigo
and probably higher).
</p>
        <p>
See also: 
</p>
        <p>
          <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a2345b18-13e4-4f60-b798-4b28587a18cb&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2011%2f01%2f24%2fYieldReturnFeatureInJava.aspx"> Yield
return feature in java</a>
          <br />
          <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a2345b18-13e4-4f60-b798-4b28587a18cb&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2011%2f01%2f27%2fWhyYieldIteratorShouldBeCloseable.aspx"> Why
@Yield iterator should be Closeable</a>
          <br />
          <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a2345b18-13e4-4f60-b798-4b28587a18cb&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2008%2f09%2f05%2fWhatYouCanDoWithJxom.aspx"> What
you can do with jxom.</a>
        </p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=a2345b18-13e4-4f60-b798-4b28587a18cb" />
      </body>
      <title>Yield return update</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,a2345b18-13e4-4f60-b798-4b28587a18cb.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2011/08/28/YieldReturnUpdate.aspx</link>
      <pubDate>Sun, 28 Aug 2011 19:11:45 GMT</pubDate>
      <description>&lt;p&gt;
Recently one of users of &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a2345b18-13e4-4f60-b798-4b28587a18cb&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2011%2f01%2f24%2fYieldReturnFeatureInJava.aspx"&gt;java
yield return annotation&lt;/a&gt; has kindly informed us about some problem that happened
in his environment (see &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a2345b18-13e4-4f60-b798-4b28587a18cb&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2011%2f02%2f05%2fJavasYieldReturnAnnotationUpdate.aspx"&gt; Java&amp;#39;s
@Yield return annotation update&lt;/a&gt;).
&lt;/p&gt;
&lt;p&gt;
Incidentally we have never noticed the problem earlier. Along with this issue we have
found that eclipse compiler has changed in the Indigo in a way that we had to recompile
the source. Well, that&amp;#39;s a price you have to pay when you access internal API.
&lt;/p&gt;
&lt;p&gt;
Updated sources can be found at &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a2345b18-13e4-4f60-b798-4b28587a18cb&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fjava%2fYield.zip"&gt;Yield.zip&lt;/a&gt;,
and compiled jars at &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a2345b18-13e4-4f60-b798-4b28587a18cb&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fjava%2fYield.jar"&gt;Yield.jar&lt;/a&gt; (pre-Indigo),
and &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a2345b18-13e4-4f60-b798-4b28587a18cb&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fjava%2fYield.3.7.jar"&gt; Yield.3.7.jar&lt;/a&gt; (Indigo
and probably higher).
&lt;/p&gt;
&lt;p&gt;
See also: 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a2345b18-13e4-4f60-b798-4b28587a18cb&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2011%2f01%2f24%2fYieldReturnFeatureInJava.aspx"&gt; Yield
return feature in java&lt;/a&gt;
&lt;br /&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a2345b18-13e4-4f60-b798-4b28587a18cb&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2011%2f01%2f27%2fWhyYieldIteratorShouldBeCloseable.aspx"&gt; Why
@Yield iterator should be Closeable&lt;/a&gt;
&lt;br /&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a2345b18-13e4-4f60-b798-4b28587a18cb&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2008%2f09%2f05%2fWhatYouCanDoWithJxom.aspx"&gt; What
you can do with jxom.&lt;/a&gt; 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=a2345b18-13e4-4f60-b798-4b28587a18cb" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,a2345b18-13e4-4f60-b798-4b28587a18cb.aspx</comments>
      <category>Announce</category>
      <category>Java</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=d653df7e-7503-4213-8546-290c3863f0e2</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,d653df7e-7503-4213-8546-290c3863f0e2.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,d653df7e-7503-4213-8546-290c3863f0e2.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=d653df7e-7503-4213-8546-290c3863f0e2</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
An xslt code that worked in the production for several years failed unexpectedly.
That's unusual, unfortunate but it happens.
</p>
        <p>
We started to analyze the problem, limited the code block and recreated it in the
simpe form. That's it:
</p>
        <p style="padding: 1em">
          <code>&lt;xsl:stylesheet version="2.0"<br />
xmlns:xsl="<a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=d653df7e-7503-4213-8546-290c3863f0e2&amp;url=http%3a%2f%2fwww.w3.org%2f1999%2fXSL%2fTransform">http://www.w3.org/1999/XSL/Transform</a>"<br />
xmlns:xs="<a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=d653df7e-7503-4213-8546-290c3863f0e2&amp;url=http%3a%2f%2fwww.w3.org%2f2001%2fXMLSchema">http://www.w3.org/2001/XMLSchema</a>"<br />
xmlns:t="<a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=d653df7e-7503-4213-8546-290c3863f0e2&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fxslt%2fpublic">http://www.nesterovsky-bros.com/xslt/public</a>"<br />
exclude-result-prefixes="t xs"&gt;<br /><br />
&lt;xsl:template match="/" name="main"&gt;<br />
&lt;xsl:variable name="content"&gt;<br />
&lt;root&gt;<br />
&lt;xsl:for-each select="1 to 3"&gt;<br />
&lt;item/&gt;<br />
&lt;/xsl:for-each&gt;<br />
&lt;/root&gt;<br />
&lt;/xsl:variable&gt;<br /><br />
&lt;xsl:variable name="result"&gt;<br />
&lt;root&gt;<br />
&lt;xsl:for-each select="$content/root/item"&gt;<br />
&lt;section-ref name-ref="<span style="font-weight: bold">{t:generate-id()}.s</span>"/&gt;<br />
&lt;!--<br />
&lt;xsl:variable name="id" as="xs:string"<br />
select="t:generate-id()"/&gt;<br />
&lt;section-ref name-ref="{$id}.s"/&gt;<br />
--&gt;<br />
&lt;/xsl:for-each&gt;<br />
&lt;/root&gt;<br />
&lt;/xsl:variable&gt;<br /><br />
&lt;xsl:message select="$result"/&gt;<br />
&lt;/xsl:template&gt;<br /><br />
&lt;xsl:function name="t:generate-id" as="xs:string"&gt;<br />
&lt;xsl:variable name="element" as="element()"&gt;<br />
&lt;element/&gt;<br />
&lt;/xsl:variable&gt;<br /><br />
&lt;xsl:sequence select="generate-id($element)"/&gt;<br />
&lt;/xsl:function&gt;<br /><br />
&lt;/xsl:stylesheet&gt; </code>
        </p>
        <p>
This code performs some transformation and assigns unique values to <code>name-ref</code> attributes.
Values generated with <code>t:generate-id()</code> function are guaranteed to be unique,
as spec claims that every node has its unique <code>generate-id()</code> value.
</p>
        <p>
Imagine, what was our surprise to find that generated elements all have the same <code>name-ref</code>'s.
We studied code all over, and found no holes in our reasoning and implementation,
so our conlusion was: it's Saxon's bug!
</p>
        <p>
It's interesting enough that if we rewrite code a little (see commented part),
it starts to work properly, thus we suspect Saxon's optimizer.
</p>
        <p>
Well, in the course of development we have found and reported many Saxon bugs, but
how come that this little beetle was hiding so long.
</p>
        <p>
We've verified that the bug exists in the versions 9.2 and 9.3. Here is the bug
report: <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=d653df7e-7503-4213-8546-290c3863f0e2&amp;url=http%3a%2f%2fsourceforge.net%2fprojects%2fsaxon%2fforums%2fforum%2f94027%2ftopic%2f4621860"> Saxon
9.2 generate-id() bug</a>. 
</p>
        <p>
Unfortunatelly, it's there already for three days (2011-07-25 to 2011-07-27) without
any reaction. We hope this will change soon.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=d653df7e-7503-4213-8546-290c3863f0e2" />
      </body>
      <title>Saxon optimizer bug</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,d653df7e-7503-4213-8546-290c3863f0e2.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2011/07/27/SaxonOptimizerBug.aspx</link>
      <pubDate>Wed, 27 Jul 2011 20:02:38 GMT</pubDate>
      <description>&lt;p&gt;
An xslt code that worked in the production for several years failed unexpectedly.
That&amp;#39;s unusual, unfortunate but it happens.
&lt;/p&gt;
&lt;p&gt;
We started to analyze the problem, limited the code block and recreated it in the
simpe form. That&amp;#39;s it:
&lt;/p&gt;
&lt;p style="padding: 1em"&gt;
&lt;code&gt;&amp;lt;xsl:stylesheet version="2.0"&lt;br /&gt;
xmlns:xsl="&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=d653df7e-7503-4213-8546-290c3863f0e2&amp;amp;url=http%3a%2f%2fwww.w3.org%2f1999%2fXSL%2fTransform"&gt;http://www.w3.org/1999/XSL/Transform&lt;/a&gt;"&lt;br /&gt;
xmlns:xs="&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=d653df7e-7503-4213-8546-290c3863f0e2&amp;amp;url=http%3a%2f%2fwww.w3.org%2f2001%2fXMLSchema"&gt;http://www.w3.org/2001/XMLSchema&lt;/a&gt;"&lt;br /&gt;
xmlns:t="&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=d653df7e-7503-4213-8546-290c3863f0e2&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fxslt%2fpublic"&gt;http://www.nesterovsky-bros.com/xslt/public&lt;/a&gt;"&lt;br /&gt;
exclude-result-prefixes="t xs"&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;xsl:template match="/" name="main"&amp;gt;&lt;br /&gt;
&amp;lt;xsl:variable name="content"&amp;gt;&lt;br /&gt;
&amp;lt;root&amp;gt;&lt;br /&gt;
&amp;lt;xsl:for-each select="1 to 3"&amp;gt;&lt;br /&gt;
&amp;lt;item/&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:for-each&amp;gt;&lt;br /&gt;
&amp;lt;/root&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:variable&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;xsl:variable name="result"&amp;gt;&lt;br /&gt;
&amp;lt;root&amp;gt;&lt;br /&gt;
&amp;lt;xsl:for-each select="$content/root/item"&amp;gt;&lt;br /&gt;
&amp;lt;section-ref name-ref="&lt;span style="font-weight: bold"&gt;{t:generate-id()}.s&lt;/span&gt;"/&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;xsl:variable name="id" as="xs:string"&lt;br /&gt;
select="t:generate-id()"/&amp;gt;&lt;br /&gt;
&amp;lt;section-ref name-ref="{$id}.s"/&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:for-each&amp;gt;&lt;br /&gt;
&amp;lt;/root&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:variable&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;xsl:message select="$result"/&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;xsl:function name="t:generate-id" as="xs:string"&amp;gt;&lt;br /&gt;
&amp;lt;xsl:variable name="element" as="element()"&amp;gt;&lt;br /&gt;
&amp;lt;element/&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:variable&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;xsl:sequence select="generate-id($element)"/&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:function&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/xsl:stylesheet&amp;gt; &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
This code performs some transformation and assigns unique values to &lt;code&gt;name-ref&lt;/code&gt; attributes.
Values generated with &lt;code&gt;t:generate-id()&lt;/code&gt; function are guaranteed to be unique,
as spec claims that every node has its unique &lt;code&gt;generate-id()&lt;/code&gt; value.
&lt;/p&gt;
&lt;p&gt;
Imagine, what was our surprise to find that generated elements all have the same &lt;code&gt;name-ref&lt;/code&gt;&amp;#39;s.
We studied code all over, and found no holes in our reasoning and implementation,
so our conlusion was: it&amp;#39;s Saxon&amp;#39;s bug!
&lt;/p&gt;
&lt;p&gt;
It&amp;#39;s interesting enough that if we rewrite code a little (see commented part),
it starts to work properly, thus we suspect Saxon&amp;#39;s optimizer.
&lt;/p&gt;
&lt;p&gt;
Well, in the course of development we have found and reported many Saxon bugs, but
how come that this little beetle was hiding so long.
&lt;/p&gt;
&lt;p&gt;
We&amp;#39;ve verified that the bug exists in the versions 9.2 and 9.3. Here is the bug
report: &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=d653df7e-7503-4213-8546-290c3863f0e2&amp;amp;url=http%3a%2f%2fsourceforge.net%2fprojects%2fsaxon%2fforums%2fforum%2f94027%2ftopic%2f4621860"&gt; Saxon
9.2 generate-id() bug&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
Unfortunatelly, it&amp;#39;s there already for three days (2011-07-25 to 2011-07-27) without
any reaction. We hope this will change soon.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=d653df7e-7503-4213-8546-290c3863f0e2" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,d653df7e-7503-4213-8546-290c3863f0e2.aspx</comments>
      <category>Tips and tricks</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=c8b061fa-7471-4601-8b19-2c5bf55ce9ea</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,c8b061fa-7471-4601-8b19-2c5bf55ce9ea.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,c8b061fa-7471-4601-8b19-2c5bf55ce9ea.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=c8b061fa-7471-4601-8b19-2c5bf55ce9ea</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We did not update <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=c8b061fa-7471-4601-8b19-2c5bf55ce9ea&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip"> languages-xom</a> already
for many monthes but now we have found a severe bug in the jxom's algorithm for eliminating
unreachable code. The marked line were considered as unreachable:
</p>
        <p style="padding-left: 1em">
          <code>check:<br />
if (condition)<br />
{<br />
break check;<br />
}<br />
else<br />
{<br />
return;<br />
}<br /><br />
// due to bug the following was considered unreachable<br /><span style="color: red; font-weight: bold">expression;</span></code>
        </p>
        <p>
Bug is fixed.
</p>
        <p>
Current update contains other cosmetic fixes. 
</p>
        <p>
Please download xslt sources from <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=c8b061fa-7471-4601-8b19-2c5bf55ce9ea&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip">languages-xom.zip</a>.
</p>
        <p>
Summary
</p>
        <p>
Languages XOM is a set of xml schemas and xslt stylesheets that allows:
</p>
        <ul>
          <li>
to define programs in xml form;</li>
          <li>
to perform transformations over code in xml form;</li>
          <li>
to generate sources.</li>
        </ul>
        <p>
Languages XOM includes:
</p>
        <ul>
          <li>
jxom - Java Xml Object model;</li>
          <li>
csharpxom - C# Xml Object Model;</li>
          <li>
cobolxom - COBOL Xml Object Model;</li>
          <li>
sqlxom - SQL Xml Object Model (including several sql dialects);</li>
          <li>
aspx - ASP.NET Object Model;</li>
        </ul>
        <p>
A proprietary part of languages XOM also includes XML Object Model for a language
named Cool:GEN. In fact the original purpose for this API was a generation of java/C#/COBOL
from Cool:GEN. For more details about Cool:GEN conversion please see <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=c8b061fa-7471-4601-8b19-2c5bf55ce9ea&amp;url=http%3a%2f%2fwww.bphx.com%2fen%2fSolutions%2fApplicationModernization%2fPages%2fCooLGen.aspx"> here</a>.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=c8b061fa-7471-4601-8b19-2c5bf55ce9ea" />
      </body>
      <title>Languages-XOM update</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,c8b061fa-7471-4601-8b19-2c5bf55ce9ea.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2011/05/26/LanguagesXOMUpdate.aspx</link>
      <pubDate>Thu, 26 May 2011 05:15:11 GMT</pubDate>
      <description>&lt;p&gt;
We did not update &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=c8b061fa-7471-4601-8b19-2c5bf55ce9ea&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip"&gt; languages-xom&lt;/a&gt; already
for many monthes but now we have found a severe bug in the jxom's algorithm for eliminating
unreachable code. The marked line were considered as unreachable:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;check:&lt;br /&gt;
if (condition)&lt;br /&gt;
{&lt;br /&gt;
break check;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// due to bug the following was considered unreachable&lt;br /&gt;
&lt;span style="color: red; font-weight: bold"&gt;expression;&lt;/span&gt; &lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
Bug is fixed.
&lt;/p&gt;
&lt;p&gt;
Current update contains other cosmetic fixes. 
&lt;/p&gt;
&lt;p&gt;
Please download xslt sources from &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=c8b061fa-7471-4601-8b19-2c5bf55ce9ea&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip"&gt;languages-xom.zip&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Summary
&lt;/p&gt;
&lt;p&gt;
Languages XOM is a set of xml schemas and xslt stylesheets that allows:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
to define programs in xml form;&lt;/li&gt;
&lt;li&gt;
to perform transformations over code in xml form;&lt;/li&gt;
&lt;li&gt;
to generate sources.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Languages XOM includes:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
jxom - Java Xml Object model;&lt;/li&gt;
&lt;li&gt;
csharpxom - C# Xml Object Model;&lt;/li&gt;
&lt;li&gt;
cobolxom - COBOL Xml Object Model;&lt;/li&gt;
&lt;li&gt;
sqlxom - SQL Xml Object Model (including several sql dialects);&lt;/li&gt;
&lt;li&gt;
aspx - ASP.NET Object Model;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
A proprietary part of languages XOM also includes XML Object Model for a language
named Cool:GEN. In fact the original purpose for this API was a generation of java/C#/COBOL
from Cool:GEN. For more details about Cool:GEN conversion please see &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=c8b061fa-7471-4601-8b19-2c5bf55ce9ea&amp;amp;url=http%3a%2f%2fwww.bphx.com%2fen%2fSolutions%2fApplicationModernization%2fPages%2fCooLGen.aspx"&gt; here&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=c8b061fa-7471-4601-8b19-2c5bf55ce9ea" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,c8b061fa-7471-4601-8b19-2c5bf55ce9ea.aspx</comments>
      <category>Announce</category>
      <category>Java</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=5ed4531a-dbbb-48b5-89d2-b58d1ed78df8</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,5ed4531a-dbbb-48b5-89d2-b58d1ed78df8.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,5ed4531a-dbbb-48b5-89d2-b58d1ed78df8.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=5ed4531a-dbbb-48b5-89d2-b58d1ed78df8</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We have updated <code>@Yield</code> annotation processor to support better debug info.
</p>
        <p>
Annotation processor can be downloaded from <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=5ed4531a-dbbb-48b5-89d2-b58d1ed78df8&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fjava%2fYield.zip">Yield.zip</a> or <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=5ed4531a-dbbb-48b5-89d2-b58d1ed78df8&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fjava%2fYield.jar">Yield.jar</a>.
</p>
        <p>
We also decided to consider jxom's state machine refactoring as obsolete as <code>@Yield</code> annotation
allows to achieve the same effect but with more clear code.
</p>
        <p>
JXOM can be downloaded from <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=5ed4531a-dbbb-48b5-89d2-b58d1ed78df8&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip"> languages-xom.zip</a></p>
        <p>
See also: 
</p>
        <p>
          <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=5ed4531a-dbbb-48b5-89d2-b58d1ed78df8&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2011%2f01%2f24%2fYieldReturnFeatureInJava.aspx">Yield
return feature in java</a>
          <br />
          <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=5ed4531a-dbbb-48b5-89d2-b58d1ed78df8&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2011%2f01%2f27%2fWhyYieldIteratorShouldBeCloseable.aspx">Why
@Yield iterator should be Closeable</a>
          <br />
          <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=5ed4531a-dbbb-48b5-89d2-b58d1ed78df8&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2008%2f09%2f05%2fWhatYouCanDoWithJxom.aspx">What
you can do with jxom.</a>
        </p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=5ed4531a-dbbb-48b5-89d2-b58d1ed78df8" />
      </body>
      <title>Java's @Yield return annotation update</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,5ed4531a-dbbb-48b5-89d2-b58d1ed78df8.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2011/02/05/JavasYieldReturnAnnotationUpdate.aspx</link>
      <pubDate>Sat, 05 Feb 2011 21:12:05 GMT</pubDate>
      <description>&lt;p&gt;
We have updated &lt;code&gt;@Yield&lt;/code&gt; annotation processor to support better debug info.
&lt;/p&gt;
&lt;p&gt;
Annotation processor can be downloaded from &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=5ed4531a-dbbb-48b5-89d2-b58d1ed78df8&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fjava%2fYield.zip"&gt;Yield.zip&lt;/a&gt; or &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=5ed4531a-dbbb-48b5-89d2-b58d1ed78df8&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fjava%2fYield.jar"&gt;Yield.jar&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
We also decided to consider jxom&amp;#39;s state machine refactoring as obsolete as &lt;code&gt;@Yield&lt;/code&gt; annotation
allows to achieve the same effect but with more clear code.
&lt;/p&gt;
&lt;p&gt;
JXOM can be downloaded from &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=5ed4531a-dbbb-48b5-89d2-b58d1ed78df8&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip"&gt; languages-xom.zip&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
See also: 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=5ed4531a-dbbb-48b5-89d2-b58d1ed78df8&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2011%2f01%2f24%2fYieldReturnFeatureInJava.aspx"&gt;Yield
return feature in java&lt;/a&gt;
&lt;br /&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=5ed4531a-dbbb-48b5-89d2-b58d1ed78df8&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2011%2f01%2f27%2fWhyYieldIteratorShouldBeCloseable.aspx"&gt;Why
@Yield iterator should be Closeable&lt;/a&gt;
&lt;br /&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=5ed4531a-dbbb-48b5-89d2-b58d1ed78df8&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2008%2f09%2f05%2fWhatYouCanDoWithJxom.aspx"&gt;What
you can do with jxom.&lt;/a&gt; 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=5ed4531a-dbbb-48b5-89d2-b58d1ed78df8" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,5ed4531a-dbbb-48b5-89d2-b58d1ed78df8.aspx</comments>
      <category>Announce</category>
      <category>Java</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=602f1d9d-bf21-4c55-86ef-c7d2ee403d6d</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,602f1d9d-bf21-4c55-86ef-c7d2ee403d6d.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,602f1d9d-bf21-4c55-86ef-c7d2ee403d6d.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=602f1d9d-bf21-4c55-86ef-c7d2ee403d6d</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p style="padding-left: 1em; font-style: italic">
          <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=602f1d9d-bf21-4c55-86ef-c7d2ee403d6d&amp;url=http%3a%2f%2ftwitter.com%2fmichaelhkay%2fstatuses%2f32946749697953793">michaelhkay</a>:
Just posted a new internal draft of XSLT 3.0. Moving forward on maps, nested sequences,
and JSON support.
</p>
        <p>
Hope they will finally appear there!
</p>
        <p>
See also: <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=602f1d9d-bf21-4c55-86ef-c7d2ee403d6d&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2008%2f08%2f30%2fTuplesAndMapsNextTry.aspx">Tuples
and maps - next try</a>, <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=602f1d9d-bf21-4c55-86ef-c7d2ee403d6d&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2008%2f07%2f10%2fTuplesAndMapsStatusCLOSEDWONTFIX.aspx"> Tuples
and maps - Status: CLOSED, WONTFIX</a>, <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=602f1d9d-bf21-4c55-86ef-c7d2ee403d6d&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2008%2f05%2f18%2fTuplesAndMapsInSaxon.aspx"> Tuples
and maps in Saxon</a> and other blog posts on our site about immutable maps.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=602f1d9d-bf21-4c55-86ef-c7d2ee403d6d" />
      </body>
      <title>Xslt 3.0 insights</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,602f1d9d-bf21-4c55-86ef-c7d2ee403d6d.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2011/02/03/Xslt30Insights.aspx</link>
      <pubDate>Thu, 03 Feb 2011 11:07:49 GMT</pubDate>
      <description>&lt;p style="padding-left: 1em; font-style: italic"&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=602f1d9d-bf21-4c55-86ef-c7d2ee403d6d&amp;amp;url=http%3a%2f%2ftwitter.com%2fmichaelhkay%2fstatuses%2f32946749697953793"&gt;michaelhkay&lt;/a&gt;:
Just posted a new internal draft of XSLT 3.0. Moving forward on maps, nested sequences,
and JSON support.
&lt;/p&gt;
&lt;p&gt;
Hope they will finally appear there!
&lt;/p&gt;
&lt;p&gt;
See also: &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=602f1d9d-bf21-4c55-86ef-c7d2ee403d6d&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2008%2f08%2f30%2fTuplesAndMapsNextTry.aspx"&gt;Tuples
and maps - next try&lt;/a&gt;, &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=602f1d9d-bf21-4c55-86ef-c7d2ee403d6d&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2008%2f07%2f10%2fTuplesAndMapsStatusCLOSEDWONTFIX.aspx"&gt; Tuples
and maps - Status: CLOSED, WONTFIX&lt;/a&gt;, &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=602f1d9d-bf21-4c55-86ef-c7d2ee403d6d&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2008%2f05%2f18%2fTuplesAndMapsInSaxon.aspx"&gt; Tuples
and maps in Saxon&lt;/a&gt; and other blog posts on our site about immutable maps.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=602f1d9d-bf21-4c55-86ef-c7d2ee403d6d" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,602f1d9d-bf21-4c55-86ef-c7d2ee403d6d.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=280d6e0d-1389-4566-9e0f-badef8530578</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,280d6e0d-1389-4566-9e0f-badef8530578.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,280d6e0d-1389-4566-9e0f-badef8530578.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=280d6e0d-1389-4566-9e0f-badef8530578</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
For some reason we never knew about instance initializer in java; on the other hand
static initializer is well known.
</p>
        <p style="padding-left: 1em;">
          <code> class A<br />
{<br />
int x;<br />
static int y;<br /><br />
// This is an instance initializer.<br />
{<br />
x = 1;<br />
}<br /><br />
// This is a static initializer.<br />
static<br />
{<br />
y = 2;<br />
}<br />
}</code>
        </p>
        <p>
Worse, we have missed it in the java grammar when we were building jxom. This way
jxom was missing the feature.
</p>
        <p>
Today we fix the miss and introduce a schema element:
</p>
        <p style="padding-left: 1em">
          <code>&lt;class-initializer static="boolean"&gt;<br />
&lt;block&gt;<br />
...<br />
&lt;/block&gt;<br />
&lt;/class-initializer&gt;</code>
        </p>
        <p>
It superseeds:
</p>
        <p style="padding-left: 1em">
          <code>&lt;static&gt;<br />
&lt;block&gt;<br />
...<br />
&lt;/block&gt;<br />
&lt;/static&gt;</code>
        </p>
        <p>
that supported static initializers alone.
</p>
        <p>
Please update <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=280d6e0d-1389-4566-9e0f-badef8530578&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip"> languages-xom
xslt stylesheets</a>.
</p>
        <p>
P.S. Out of curiosity, did you ever see any use of instance initializers?
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=280d6e0d-1389-4566-9e0f-badef8530578" />
      </body>
      <title>Java XML Object Model Update</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,280d6e0d-1389-4566-9e0f-badef8530578.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2011/01/14/JavaXMLObjectModelUpdate.aspx</link>
      <pubDate>Fri, 14 Jan 2011 21:29:04 GMT</pubDate>
      <description>&lt;p&gt;
For some reason we never knew about instance initializer in java; on the other hand
static initializer is well known.
&lt;/p&gt;
&lt;p style="padding-left: 1em;"&gt;
&lt;code&gt; class A&lt;br /&gt;
{&lt;br /&gt;
int x;&lt;br /&gt;
static int y;&lt;br /&gt;
&lt;br /&gt;
// This is an instance initializer.&lt;br /&gt;
{&lt;br /&gt;
x = 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// This is a static initializer.&lt;br /&gt;
static&lt;br /&gt;
{&lt;br /&gt;
y = 2;&lt;br /&gt;
}&lt;br /&gt;
}&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Worse, we have missed it in the java grammar when we were building jxom. This way
jxom was missing the feature.
&lt;/p&gt;
&lt;p&gt;
Today we fix the miss and introduce a schema element:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&amp;lt;class-initializer static=&amp;quot;boolean&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;block&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/block&amp;gt;&lt;br /&gt;
&amp;lt;/class-initializer&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
It superseeds:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&amp;lt;static&amp;gt;&lt;br /&gt;
&amp;lt;block&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/block&amp;gt;&lt;br /&gt;
&amp;lt;/static&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
that supported static initializers alone.
&lt;/p&gt;
&lt;p&gt;
Please update &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=280d6e0d-1389-4566-9e0f-badef8530578&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip"&gt; languages-xom
xslt stylesheets&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
P.S. Out of curiosity, did you ever see any use of instance initializers?
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=280d6e0d-1389-4566-9e0f-badef8530578" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,280d6e0d-1389-4566-9e0f-badef8530578.aspx</comments>
      <category>Announce</category>
      <category>Java</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=ebd5185f-fc37-4e82-b2bb-006387635512</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,ebd5185f-fc37-4e82-b2bb-006387635512.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,ebd5185f-fc37-4e82-b2bb-006387635512.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=ebd5185f-fc37-4e82-b2bb-006387635512</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We could not stand the temptation to implement the <code>@Yield</code> annotation
that we described <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=ebd5185f-fc37-4e82-b2bb-006387635512&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2010%2f12%2f20%2fYieldFeatureInJava.aspx">earlier</a>.
</p>
        <p>
Idea is rather clear but people are saying that it's not an easy task to update
the sources.
</p>
        <p>
They were right!
</p>
        <p>
Implementation has its price, as we were forced to access JDK's classes of javac
compiler. As result, at present, we don't support other compilers such as EclipseCompiler.
We shall look later what can be done in this area.
</p>
        <p>
At present, annotation processor works perfectly when you run javac either from the
command line, from ant, or from other build tool.
</p>
        <p>
Here is an example of how method is refactored:
</p>
        <p style="padding-left: 1em">
          <code>@Yield<br />
public static Iterable&lt;Long&gt; fibonachi()<br />
{<br />
ArrayList&lt;Long&gt; items = new ArrayList&lt;Long&gt;();<br /><br />
long Ti = 0;<br />
long Ti1 = 1;<br /><br />
while(true)<br />
{<br />
items.add(Ti);<br /><br />
long value = Ti + Ti1;<br /><br />
Ti = Ti1;<br />
Ti1 = value;<br />
}<br />
}</code>
        </p>
        <p>
And that's how we transform it:
</p>
        <p style="padding-left: 1em">
          <code>@Yield()<br />
public static Iterable&lt;Long&gt; fibonachi() {<br />
assert (java.util.ArrayList&lt;Long&gt;)(ArrayList&lt;Long&gt;)null == null : null;<br /><br />
class $state$ implements java.lang.Iterable&lt;Long&gt;, java.util.Iterator&lt;Long&gt;,
java.io.Closeable {<br /><br />
public java.util.Iterator&lt;Long&gt; iterator() {<br />
if ($state$id == 0) {<br />
$state$id = 1;<br />
return this;<br />
} else return new $state$();<br />
}<br /><br />
public boolean hasNext() {<br />
if (!$state$nextDefined) {<br />
$state$hasNext = $state$next();<br />
$state$nextDefined = true;<br />
}<br /><br />
return $state$hasNext;<br />
}<br /><br />
public Long next() {<br />
if (!hasNext()) throw new java.util.NoSuchElementException();<br /><br />
$state$nextDefined = false;<br /><br />
return $state$next;<br />
}<br /><br />
public void remove() {<br />
throw new java.lang.UnsupportedOperationException();<br />
}<br /><br />
public void close() {<br />
$state$id = 5;<br />
}<br /><br />
private boolean $state$next() {<br />
while (true) switch ($state$id) {<br />
case 0:<br />
$state$id = 1;<br />
case 1:<br />
Ti = 0;<br />
Ti1 = 1;<br />
case 2: 
<br />
if (!true) {<br />
$state$id = 4;<br />
break;<br />
}<br /><br />
$state$next = Ti;<br />
$state$id = 3;<br /><br />
return true;<br />
case 3: 
<br />
value = Ti + Ti1;<br />
Ti = Ti1;<br />
Ti1 = value;<br />
$state$id = 2;<br /><br />
break;<br />
case 4: 
<br />
case 5: 
<br />
default: 
<br />
$state$id = 5;<br /><br />
return false;<br />
}<br />
}<br /><br />
private long Ti;<br />
private long Ti1;<br />
private long value;<br />
private int $state$id;<br />
private boolean $state$hasNext;<br />
private boolean $state$nextDefined;<br />
private Long $state$next;<br />
}<br /><br />
return new $state$();<br />
}</code>
        </p>
        <p>
Formatting is automatic, sorry, but anyway it's for diagnostics only. You will
never see this code.
</p>
        <p>
It's iteresting to say that this implementation is very precisely mimics <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=ebd5185f-fc37-4e82-b2bb-006387635512&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2008%2f09%2f05%2fWhatYouCanDoWithJxom.aspx"> xslt
state machine implementation</a> we have done back in 2008.
</p>
        <p>
You can <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=ebd5185f-fc37-4e82-b2bb-006387635512&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fjava%2fYield.zip"> download
YieldProcessor here</a>. We hope that someone will find our solution very interesting.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=ebd5185f-fc37-4e82-b2bb-006387635512" />
      </body>
      <title>Yield feature in java implemented!</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,ebd5185f-fc37-4e82-b2bb-006387635512.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2011/01/11/YieldFeatureInJavaImplemented.aspx</link>
      <pubDate>Tue, 11 Jan 2011 16:08:41 GMT</pubDate>
      <description>&lt;p&gt;
We could not stand the temptation to implement the &lt;code&gt;@Yield&lt;/code&gt; annotation
that we described &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=ebd5185f-fc37-4e82-b2bb-006387635512&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2010%2f12%2f20%2fYieldFeatureInJava.aspx"&gt;earlier&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Idea is rather clear but people are saying that it&amp;#39;s not an easy task to update
the sources.
&lt;/p&gt;
&lt;p&gt;
They were right!
&lt;/p&gt;
&lt;p&gt;
Implementation has its price, as we were forced to access JDK&amp;#39;s classes of javac
compiler. As result, at present, we don&amp;#39;t support other compilers such as EclipseCompiler.
We shall look later what can be done in this area.
&lt;/p&gt;
&lt;p&gt;
At present, annotation processor works perfectly when you run javac either from the
command line, from ant, or from other build tool.
&lt;/p&gt;
&lt;p&gt;
Here is an example of how method is refactored:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;@Yield&lt;br /&gt;
public static Iterable&amp;lt;Long&amp;gt; fibonachi()&lt;br /&gt;
{&lt;br /&gt;
ArrayList&amp;lt;Long&amp;gt; items = new ArrayList&amp;lt;Long&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
long Ti = 0;&lt;br /&gt;
long Ti1 = 1;&lt;br /&gt;
&lt;br /&gt;
while(true)&lt;br /&gt;
{&lt;br /&gt;
items.add(Ti);&lt;br /&gt;
&lt;br /&gt;
long value = Ti + Ti1;&lt;br /&gt;
&lt;br /&gt;
Ti = Ti1;&lt;br /&gt;
Ti1 = value;&lt;br /&gt;
}&lt;br /&gt;
}&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
And that&amp;#39;s how we transform it:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;@Yield()&lt;br /&gt;
public static Iterable&amp;lt;Long&amp;gt; fibonachi() {&lt;br /&gt;
assert (java.util.ArrayList&amp;lt;Long&amp;gt;)(ArrayList&amp;lt;Long&amp;gt;)null == null : null;&lt;br /&gt;
&lt;br /&gt;
class $state$ implements java.lang.Iterable&amp;lt;Long&amp;gt;, java.util.Iterator&amp;lt;Long&amp;gt;,
java.io.Closeable {&lt;br /&gt;
&lt;br /&gt;
public java.util.Iterator&amp;lt;Long&amp;gt; iterator() {&lt;br /&gt;
if ($state$id == 0) {&lt;br /&gt;
$state$id = 1;&lt;br /&gt;
return this;&lt;br /&gt;
} else return new $state$();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public boolean hasNext() {&lt;br /&gt;
if (!$state$nextDefined) {&lt;br /&gt;
$state$hasNext = $state$next();&lt;br /&gt;
$state$nextDefined = true;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return $state$hasNext;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Long next() {&lt;br /&gt;
if (!hasNext()) throw new java.util.NoSuchElementException();&lt;br /&gt;
&lt;br /&gt;
$state$nextDefined = false;&lt;br /&gt;
&lt;br /&gt;
return $state$next;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public void remove() {&lt;br /&gt;
throw new java.lang.UnsupportedOperationException();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public void close() {&lt;br /&gt;
$state$id = 5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private boolean $state$next() {&lt;br /&gt;
while (true) switch ($state$id) {&lt;br /&gt;
case 0:&lt;br /&gt;
$state$id = 1;&lt;br /&gt;
case 1:&lt;br /&gt;
Ti = 0;&lt;br /&gt;
Ti1 = 1;&lt;br /&gt;
case 2: 
&lt;br /&gt;
if (!true) {&lt;br /&gt;
$state$id = 4;&lt;br /&gt;
break;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$state$next = Ti;&lt;br /&gt;
$state$id = 3;&lt;br /&gt;
&lt;br /&gt;
return true;&lt;br /&gt;
case 3: 
&lt;br /&gt;
value = Ti + Ti1;&lt;br /&gt;
Ti = Ti1;&lt;br /&gt;
Ti1 = value;&lt;br /&gt;
$state$id = 2;&lt;br /&gt;
&lt;br /&gt;
break;&lt;br /&gt;
case 4: 
&lt;br /&gt;
case 5: 
&lt;br /&gt;
default: 
&lt;br /&gt;
$state$id = 5;&lt;br /&gt;
&lt;br /&gt;
return false;&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private long Ti;&lt;br /&gt;
private long Ti1;&lt;br /&gt;
private long value;&lt;br /&gt;
private int $state$id;&lt;br /&gt;
private boolean $state$hasNext;&lt;br /&gt;
private boolean $state$nextDefined;&lt;br /&gt;
private Long $state$next;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return new $state$();&lt;br /&gt;
}&lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
Formatting is automatic, sorry, but anyway it&amp;#39;s for diagnostics only. You will
never see this code.
&lt;/p&gt;
&lt;p&gt;
It&amp;#39;s iteresting to say that this implementation is very precisely mimics &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=ebd5185f-fc37-4e82-b2bb-006387635512&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2008%2f09%2f05%2fWhatYouCanDoWithJxom.aspx"&gt; xslt
state machine implementation&lt;/a&gt; we have done back in 2008.
&lt;/p&gt;
&lt;p&gt;
You can &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=ebd5185f-fc37-4e82-b2bb-006387635512&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fjava%2fYield.zip"&gt; download
YieldProcessor here&lt;/a&gt;. We hope that someone will find our solution very interesting.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=ebd5185f-fc37-4e82-b2bb-006387635512" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,ebd5185f-fc37-4e82-b2bb-006387635512.aspx</comments>
      <category>Announce</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
      <category>xslt</category>
      <category>Java</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=adb797fe-a781-423c-8dea-ea827d86241b</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,adb797fe-a781-423c-8dea-ea827d86241b.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,adb797fe-a781-423c-8dea-ea827d86241b.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=adb797fe-a781-423c-8dea-ea827d86241b</wfw:commentRss>
      <title>Yield feature in java</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,adb797fe-a781-423c-8dea-ea827d86241b.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/12/20/YieldFeatureInJava.aspx</link>
      <pubDate>Mon, 20 Dec 2010 16:28:35 GMT</pubDate>
      <description>&lt;p&gt;
Several times we have already wished to see &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=adb797fe-a781-423c-8dea-ea827d86241b&amp;amp;url=http%3a%2f%2fstackoverflow.com%2fquestions%2f1980953%2fis-there-a-java-equivalent-to-cs-yield-keyword"&gt; &lt;code&gt;yield&lt;/code&gt; feature
in java&lt;/a&gt; and all the time came to the same implementation: &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=adb797fe-a781-423c-8dea-ea827d86241b&amp;amp;url=http%3a%2f%2fcode.google.com%2fp%2finfomancers-collections%2f"&gt;infomancers-collections&lt;/a&gt;.
And every time with dissatisfaction turned away, and continued with regular iterators.
&lt;/p&gt;
&lt;p&gt;
Why? Well, in spite of the fact it's the best implementation of the feature we have
seen, it's still too heavy, as it's playing with java byte code at run-time.
&lt;/p&gt;
&lt;p&gt;
We never grasped the idea why it's done this way, while there is &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=adb797fe-a781-423c-8dea-ea827d86241b&amp;amp;url=http%3a%2f%2fdownload.oracle.com%2fjavase%2f1.5.0%2fdocs%2fguide%2fapt%2fGettingStarted.html"&gt;post-compile
time annotation processing in java&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
If we would implemented the yeild feature in java we would created a &lt;code&gt;@Yield&lt;/code&gt; annotation
and would demanded to implement some well defined code pattern like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; @Yield&lt;br /&gt;
Iteratable&amp;lt;String&gt; iterator()&lt;br /&gt;
{ 
&lt;br /&gt;
// This is part of pattern.&lt;br /&gt;
ArrayList&amp;lt;String&gt; list = new ArrayList&amp;lt;String&gt;();&lt;br /&gt;
&lt;br /&gt;&lt; 10; ++i)&lt;br /&gt;
for(int i = 0; i {&lt;br /&gt;
// list.add() plays the role of yield return.&lt;br /&gt;
list.add(String.valueOf(i));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// This is part of pattern.&lt;br /&gt;
return list;&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
or
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; @Yield&lt;br /&gt;
Iterator&amp;lt;String&gt; iterator()&lt;br /&gt;
{&lt;br /&gt;
// This is part of pattern.&lt;br /&gt;
ArrayList&amp;lt;String&gt; list = new ArrayList&amp;lt;String&gt;();&lt;br /&gt;
&lt;br /&gt;&lt; 10; ++i)&lt;br /&gt;
for(int i = 0; i {&lt;br /&gt;
// list.add() plays the role of yield return.&lt;br /&gt;
list.add(String.valueOf(i));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// This is part of pattern.&lt;br /&gt;
return list.iterator();&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Note that the code will work correctly even, if by mischance, post-compile-time processing
will not take place.
&lt;/p&gt;
&lt;p&gt;
At post comile time we would do all required refactoring to turn these implementations
into a state machines thus runtime would not contain any third party components.
&lt;/p&gt;
&lt;p&gt;
It's iteresting to recall that we have also implemented similar refactoring in pure
xslt.
&lt;/p&gt;
&lt;p&gt;
See &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=adb797fe-a781-423c-8dea-ea827d86241b&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2008%2f09%2f05%2fWhatYouCanDoWithJxom.aspx" rel="bookmark"&gt;What
you can do with jxom&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;Update:&lt;/b&gt; implementation can be found at &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=adb797fe-a781-423c-8dea-ea827d86241b&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fjava%2fYield.zip"&gt;Yield.zip&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=adb797fe-a781-423c-8dea-ea827d86241b" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,adb797fe-a781-423c-8dea-ea827d86241b.aspx</comments>
      <category>Java</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=ec1ae7ee-1c88-44a2-a6f1-d8a2f9ba5571</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,ec1ae7ee-1c88-44a2-a6f1-d8a2f9ba5571.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,ec1ae7ee-1c88-44a2-a6f1-d8a2f9ba5571.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=ec1ae7ee-1c88-44a2-a6f1-d8a2f9ba5571</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Michael Key, author of the Saxon xslt processor, being inspired by the GWT ideas,
has decided to compile Saxon HE into javascript. See <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=ec1ae7ee-1c88-44a2-a6f1-d8a2f9ba5571&amp;url=http%3a%2f%2fsaxonica.blogharbor.com%2fblog%2f_archives%2f2010%2f11%2f16%2f4681337.html"> Compiling
Saxon using GWT</a>.
</p>
        <p>
The resulting script is about 1MB of size.
</p>
        <p>
But what we thought lately, that it's overkill to bring whole xslt engine on a client,
while it's possible to generate javascript from xslt the same way as he's building
java from xquery. This will probably require some runtime but of much lesser size.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=ec1ae7ee-1c88-44a2-a6f1-d8a2f9ba5571" />
      </body>
      <title>A shallow thoughts</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,ec1ae7ee-1c88-44a2-a6f1-d8a2f9ba5571.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/11/18/AShallowThoughts.aspx</link>
      <pubDate>Thu, 18 Nov 2010 16:19:52 GMT</pubDate>
      <description>&lt;p&gt;
Michael Key, author of the Saxon xslt processor, being inspired by the GWT ideas,
has decided to compile Saxon HE into javascript. See &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=ec1ae7ee-1c88-44a2-a6f1-d8a2f9ba5571&amp;amp;url=http%3a%2f%2fsaxonica.blogharbor.com%2fblog%2f_archives%2f2010%2f11%2f16%2f4681337.html"&gt; Compiling
Saxon using GWT&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
The resulting script is about 1MB of size.
&lt;/p&gt;
&lt;p&gt;
But what we thought lately, that it's overkill to bring whole xslt engine on a client,
while it's possible to generate javascript from xslt the same way as he's building
java from xquery. This will probably require some runtime but of much lesser size.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=ec1ae7ee-1c88-44a2-a6f1-d8a2f9ba5571" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,ec1ae7ee-1c88-44a2-a6f1-d8a2f9ba5571.aspx</comments>
      <category>Tips and tricks</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=a34cff72-b6f4-4c4c-832e-2799b0358398</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,a34cff72-b6f4-4c4c-832e-2799b0358398.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,a34cff72-b6f4-4c4c-832e-2799b0358398.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=a34cff72-b6f4-4c4c-832e-2799b0358398</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <b>Search at www.google.fr:</b> An empty sequence is not allowed as the @select attribute
of xsl:analyze-string
</p>
        <p>
That's known issue. See <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a34cff72-b6f4-4c4c-832e-2799b0358398&amp;url=http%3a%2f%2fwww.w3.org%2fBugs%2fPublic%2fshow_bug.cgi%3fid%3d7976">Bug
7976</a>.
</p>
        <p>
In xslt 2.0 you should either check the value before using xsl:analyze-string, or
wrap it into <code>string()</code> call.
</p>
        <p>
The problem is addressed in xslt 3.0
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=a34cff72-b6f4-4c4c-832e-2799b0358398" />
      </body>
      <title>xsl:analyze-string (www.google.fr)</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,a34cff72-b6f4-4c4c-832e-2799b0358398.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/11/09/xslanalyzestringWwwgooglefr.aspx</link>
      <pubDate>Tue, 09 Nov 2010 10:11:45 GMT</pubDate>
      <description>&lt;p&gt;
&lt;b&gt;Search at www.google.fr:&lt;/b&gt; An empty sequence is not allowed as the @select attribute
of xsl:analyze-string
&lt;/p&gt;
&lt;p&gt;
That's known issue. See &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a34cff72-b6f4-4c4c-832e-2799b0358398&amp;amp;url=http%3a%2f%2fwww.w3.org%2fBugs%2fPublic%2fshow_bug.cgi%3fid%3d7976"&gt;Bug
7976&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
In xslt 2.0 you should either check the value before using xsl:analyze-string, or
wrap it into &lt;code&gt;string()&lt;/code&gt; call.
&lt;/p&gt;
&lt;p&gt;
The problem is addressed in xslt 3.0
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=a34cff72-b6f4-4c4c-832e-2799b0358398" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,a34cff72-b6f4-4c4c-832e-2799b0358398.aspx</comments>
      <category>Tips and tricks</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=4a7e718d-5294-4dfd-99b7-84a301d9f848</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,4a7e718d-5294-4dfd-99b7-84a301d9f848.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,4a7e718d-5294-4dfd-99b7-84a301d9f848.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=4a7e718d-5294-4dfd-99b7-84a301d9f848</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p style="padding-left:1em; font-style: italic">
          <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=4a7e718d-5294-4dfd-99b7-84a301d9f848&amp;url=http%3a%2f%2ftwitter.com%2fmichaelhkay%2fstatuses%2f979839762833408">michaelhkay:</a> Saxon
9.3 has been out for 8 days: only two bugs so far, one found by me. I think that's
a record. 
</p>
        <p>
Not necessary. We, for example, who use Saxon HE, have found nothing new in Saxon
9.3, while expected to see xslt 3.0. Disappointed. No actual reason to migrate.
</p>
        <p>
P.S. We were among the first who were finding early bugs in previous releases.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=4a7e718d-5294-4dfd-99b7-84a301d9f848" />
      </body>
      <title>Saxon 9.3</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,4a7e718d-5294-4dfd-99b7-84a301d9f848.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/11/07/Saxon93.aspx</link>
      <pubDate>Sun, 07 Nov 2010 09:07:11 GMT</pubDate>
      <description>&lt;p style="padding-left:1em; font-style: italic"&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=4a7e718d-5294-4dfd-99b7-84a301d9f848&amp;amp;url=http%3a%2f%2ftwitter.com%2fmichaelhkay%2fstatuses%2f979839762833408"&gt;michaelhkay:&lt;/a&gt; Saxon
9.3 has been out for 8 days: only two bugs so far, one found by me. I think that's
a record. 
&lt;/p&gt;
&lt;p&gt;
Not necessary. We, for example, who use Saxon HE, have found nothing new in Saxon
9.3, while expected to see xslt 3.0. Disappointed. No actual reason to migrate.
&lt;/p&gt;
&lt;p&gt;
P.S. We were among the first who were finding early bugs in previous releases.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=4a7e718d-5294-4dfd-99b7-84a301d9f848" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,4a7e718d-5294-4dfd-99b7-84a301d9f848.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=06e07811-9b5b-4cf2-a14b-77df02faace7</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,06e07811-9b5b-4cf2-a14b-77df02faace7.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,06e07811-9b5b-4cf2-a14b-77df02faace7.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=06e07811-9b5b-4cf2-a14b-77df02faace7</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We're following w3's "<a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=06e07811-9b5b-4cf2-a14b-77df02faace7&amp;url=http%3a%2f%2fwww.w3.org%2fBugs%2fPublic%2fshow_bug.cgi%3fid%3d9069">Bug
9069</a> - Function to invoke an XSLT transformation".
</p>
        <p>
There, people argue about xpath API to invoke xslt transformations. Function should
look roughly like this:
</p>
        <p style="padding-left: 1em">
          <code>transform<br />
(<br />
  $node-tree as node()?, 
<br />
  $stylesheet as item(), 
<br />
  $parameters as XXX<br />
) as node()</code>
        </p>
        <p>
The discussion is spinning around the last argument: <code>$parameters as XXX</code>.
Should it be an xml element describing parameters, a function returning values for
parameter names, or some new type modelling immutable map?
</p>
        <p>
What is most interesting in this discussion is the leak about plans to introduce a
map type:
</p>
        <div style="padding-left: 1em; font-style: italic">
          <div style="background-color: #e0e0e0;">
            <span style="float: right;">
              <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=06e07811-9b5b-4cf2-a14b-77df02faace7&amp;url=http%3a%2f%2fwww.w3.org%2fBugs%2fPublic%2fshow_bug.cgi%3fid%3d9069%23c7"> Comment
7</a>
            </span> Michael Kay, 2010-09-14 22:46:58 UTC 
</div>
          <br />
          <div>
We're currently talking about adding an immutable map to XSLT as a new data type
(the put operation would return a new map). There appear to be a number of possible
efficient implementations. It would be ideally suited for this purpose, because unlike
the mechanism used for serialization parameters, the values can be any data type (including
nodes), not only strings. 
</div>
          <br />
        </div>
        <p>
There is a hope that map will finally appear in xslt!
</p>
        <p>
See also: 
<br /><a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=06e07811-9b5b-4cf2-a14b-77df02faace7&amp;url=http%3a%2f%2fwww.w3.org%2fBugs%2fPublic%2fshow_bug.cgi%3fid%3d5630">Bug 5630</a> -
[DM] Tuples and maps, 
<br /><a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=06e07811-9b5b-4cf2-a14b-77df02faace7&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2008%2f07%2f10%2fTuplesAndMapsStatusCLOSEDWONTFIX.aspx" rel="bookmark">Tuples
and maps - Status: CLOSED, WONTFIX</a>,<br /><a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=06e07811-9b5b-4cf2-a14b-77df02faace7&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2010%2f02%2f06%2fMapBasedOnImmutableTrees.aspx" rel="bookmark">Map,
based on immutable trees</a>,<br /><a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=06e07811-9b5b-4cf2-a14b-77df02faace7&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2010%2f03%2f15%2fMapsInExslt2.aspx" rel="bookmark">Maps
in exslt2?</a></p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=06e07811-9b5b-4cf2-a14b-77df02faace7" />
      </body>
      <title>w3's bugzilla entry 9069</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,06e07811-9b5b-4cf2-a14b-77df02faace7.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/11/02/w3sBugzillaEntry9069.aspx</link>
      <pubDate>Tue, 02 Nov 2010 08:34:52 GMT</pubDate>
      <description>&lt;p&gt;
We&amp;#39;re following w3&amp;#39;s &amp;quot;&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=06e07811-9b5b-4cf2-a14b-77df02faace7&amp;amp;url=http%3a%2f%2fwww.w3.org%2fBugs%2fPublic%2fshow_bug.cgi%3fid%3d9069"&gt;Bug
9069&lt;/a&gt; - Function to invoke an XSLT transformation&amp;quot;.
&lt;/p&gt;
&lt;p&gt;
There, people argue about xpath API to invoke xslt transformations. Function should
look roughly like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;transform&lt;br /&gt;
(&lt;br /&gt;
&amp;nbsp; $node-tree as node()?, 
&lt;br /&gt;
&amp;nbsp; $stylesheet as item(), 
&lt;br /&gt;
&amp;nbsp; $parameters as XXX&lt;br /&gt;
) as node()&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
The discussion is spinning around the last argument: &lt;code&gt;$parameters as XXX&lt;/code&gt;.
Should it be an xml element describing parameters, a function returning values for
parameter names, or some new type modelling immutable map?
&lt;/p&gt;
&lt;p&gt;
What is most interesting in this discussion is the leak about plans to introduce a
map type:
&lt;/p&gt;
&lt;div style="padding-left: 1em; font-style: italic"&gt;
&lt;div style="background-color: #e0e0e0;"&gt;
&lt;span style="float: right;"&gt;&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=06e07811-9b5b-4cf2-a14b-77df02faace7&amp;amp;url=http%3a%2f%2fwww.w3.org%2fBugs%2fPublic%2fshow_bug.cgi%3fid%3d9069%23c7"&gt; Comment
7&lt;/a&gt;&lt;/span&gt; Michael Kay, 2010-09-14 22:46:58 UTC 
&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;
We&amp;#39;re currently talking about adding an immutable map to XSLT as a new data type
(the put operation would return a new map). There appear to be a number of possible
efficient implementations. It would be ideally suited for this purpose, because unlike
the mechanism used for serialization parameters, the values can be any data type (including
nodes), not only strings. 
&lt;/div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
There is a hope that map will finally appear in xslt!
&lt;/p&gt;
&lt;p&gt;
See also: 
&lt;br /&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=06e07811-9b5b-4cf2-a14b-77df02faace7&amp;amp;url=http%3a%2f%2fwww.w3.org%2fBugs%2fPublic%2fshow_bug.cgi%3fid%3d5630"&gt;Bug&amp;nbsp;5630&lt;/a&gt; -
[DM] Tuples and maps, 
&lt;br /&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=06e07811-9b5b-4cf2-a14b-77df02faace7&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2008%2f07%2f10%2fTuplesAndMapsStatusCLOSEDWONTFIX.aspx" rel="bookmark"&gt;Tuples
and maps - Status: CLOSED, WONTFIX&lt;/a&gt;,&lt;br /&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=06e07811-9b5b-4cf2-a14b-77df02faace7&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2010%2f02%2f06%2fMapBasedOnImmutableTrees.aspx" rel="bookmark"&gt;Map,
based on immutable trees&lt;/a&gt;,&lt;br /&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=06e07811-9b5b-4cf2-a14b-77df02faace7&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2010%2f03%2f15%2fMapsInExslt2.aspx" rel="bookmark"&gt;Maps
in exslt2?&lt;/a&gt; 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=06e07811-9b5b-4cf2-a14b-77df02faace7" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,06e07811-9b5b-4cf2-a14b-77df02faace7.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=0fdc7420-9599-4b14-979f-5b95ec6df7c9</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,0fdc7420-9599-4b14-979f-5b95ec6df7c9.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,0fdc7420-9599-4b14-979f-5b95ec6df7c9.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=0fdc7420-9599-4b14-979f-5b95ec6df7c9</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Historically <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=0fdc7420-9599-4b14-979f-5b95ec6df7c9&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2fct.ashx%3fid%3d0fdc7420-9599-4b14-979f-5b95ec6df7c9%26url%3dhttp%253a%252f%252fwww.nesterovsky-bros.com%252fdownload%252flanguages-xom.zip"> jxom</a> was
developed first, and as such exhibited some imperfectness in its xml schema. <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=0fdc7420-9599-4b14-979f-5b95ec6df7c9&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2fct.ashx%3fid%3d0fdc7420-9599-4b14-979f-5b95ec6df7c9%26url%3dhttp%253a%252f%252fwww.nesterovsky-bros.com%252fdownload%252flanguages-xom.zip"> csharpxom</a> has
taken into an account jxom's problems.
</p>
        <p>
Unfortunately we could not easily fix jxom as a great amount of code already uses
it. In this refactoring we tried to be conservative, and have changed only <code>"type"</code> and <code>"import"</code> xml
schema elements in java.xsd.
</p>
        <p>
Consider type reference and package import constructs in the old schema:
</p>
        <p style="PADDING-LEFT: 1em">
          <code>&lt;!-- import java.util.ArrayList; --&gt;<br />
&lt;import name="java.util.ArrayList"/&gt;<br /><br />
&lt;!-- java.util.ArrayList&lt;java.math.BigDecimal&gt; --&gt;<br />
&lt;type package="java.util"&gt;<br />
&lt;part name="ArrayList"&gt;<br />
&lt;argument&gt;<br />
&lt;type name="BigDecimal" package="java.math"&gt;<br />
&lt;/argument&gt;<br />
&lt;/part&gt;<br />
&lt;/type&gt;<br /><br />
&lt;!-- my.Parent.Nested --&gt;<br />
&lt;type package="my"&gt;<br />
&lt;part name="Parent"/&gt;<br />
&lt;part name="Nested"/&gt;<br />
&lt;type&gt;</code>
        </p>
        <p>
Here we can observe that:
</p>
        <ul>
          <li>
type is referred by a qualified name in import element;</li>
          <li>
type has two forms: simple (see BigDecimal), and other for nested or generic type
(see ArrayList).</li>
        </ul>
        <p>
We have made it more consistent in the updated jxom:
</p>
        <p style="PADDING-LEFT: 1em">
          <code>&lt;!-- import java.util.ArrayList; --&gt;<br />
&lt;import&gt;<br />
&lt;type name="ArrayList" package="java.util"/&gt;<br />
&lt;/import&gt;<br /><br />
&lt;!-- java.util.ArrayList&lt;java.math.BigDecimal&gt; --&gt;<br />
&lt;type name="ArrayList" package="java.util"&gt;<br />
&lt;argument&gt;<br />
&lt;type name="BigDecimal" package="java.math"&gt;<br />
&lt;/argument&gt;<br />
&lt;/type&gt;<br /><br />
&lt;!-- my.Parent.Nested --&gt;<br />
&lt;type name="Nested"&gt;<br />
&lt;type name="Parent" package="my"/&gt;<br />
&lt;type&gt;</code>
        </p>
        <p>
We hope that you will not be impacted very much by this fix.
</p>
        <p>
Please refresh Languages XOM from <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=0fdc7420-9599-4b14-979f-5b95ec6df7c9&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2fct.ashx%3fid%3d0fdc7420-9599-4b14-979f-5b95ec6df7c9%26url%3dhttp%253a%252f%252fwww.nesterovsky-bros.com%252fdownload%252flanguages-xom.zip"> languages-xom.zip</a>.
</p>
        <p>
P.S. we have also included xml schema and xslt api to generate ASPX (see <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=0fdc7420-9599-4b14-979f-5b95ec6df7c9&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2fct.ashx%3fid%3d0fdc7420-9599-4b14-979f-5b95ec6df7c9%26url%3dhttp%253a%252f%252fwww.nesterovsky-bros.com%252fweblog%252f2010%252f06%252f22%252fXsltSerializerForASPXOutput.aspx"> Xslt
serializer for ASPX output</a>). We, in fact, in our projects, generate aspx documents
with embedded csharpxom, and then pass it through two stage transformation.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=0fdc7420-9599-4b14-979f-5b95ec6df7c9" />
      </body>
      <title>Languages xom update</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,0fdc7420-9599-4b14-979f-5b95ec6df7c9.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/11/01/LanguagesXomUpdate.aspx</link>
      <pubDate>Mon, 01 Nov 2010 15:48:19 GMT</pubDate>
      <description>  &lt;p&gt;
Historically &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=0fdc7420-9599-4b14-979f-5b95ec6df7c9&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2fct.ashx%3fid%3d0fdc7420-9599-4b14-979f-5b95ec6df7c9%26url%3dhttp%253a%252f%252fwww.nesterovsky-bros.com%252fdownload%252flanguages-xom.zip"&gt; jxom&lt;/a&gt; was
developed first, and as such exhibited some imperfectness in its xml schema. &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=0fdc7420-9599-4b14-979f-5b95ec6df7c9&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2fct.ashx%3fid%3d0fdc7420-9599-4b14-979f-5b95ec6df7c9%26url%3dhttp%253a%252f%252fwww.nesterovsky-bros.com%252fdownload%252flanguages-xom.zip"&gt; csharpxom&lt;/a&gt; has
taken into an account jxom&amp;#39;s problems.
&lt;/p&gt;
&lt;p&gt;
Unfortunately we could not easily fix jxom as a great amount of code already uses
it. In this refactoring we tried to be conservative, and have changed only &lt;code&gt;&amp;quot;type&amp;quot;&lt;/code&gt; and &lt;code&gt;&amp;quot;import&amp;quot;&lt;/code&gt; xml
schema elements in java.xsd.
&lt;/p&gt;
&lt;p&gt;
Consider type reference and package import constructs in the old schema:
&lt;/p&gt;
&lt;p style="PADDING-LEFT: 1em"&gt;
&lt;code&gt;&amp;lt;!-- import java.util.ArrayList; --&amp;gt;&lt;br /&gt;
&amp;lt;import name=&amp;quot;java.util.ArrayList&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- java.util.ArrayList&amp;lt;java.math.BigDecimal&amp;gt; --&amp;gt;&lt;br /&gt;
&amp;lt;type package=&amp;quot;java.util&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;part name=&amp;quot;ArrayList&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;argument&amp;gt;&lt;br /&gt;
&amp;lt;type name=&amp;quot;BigDecimal&amp;quot; package=&amp;quot;java.math&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/argument&amp;gt;&lt;br /&gt;
&amp;lt;/part&amp;gt;&lt;br /&gt;
&amp;lt;/type&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- my.Parent.Nested --&amp;gt;&lt;br /&gt;
&amp;lt;type package=&amp;quot;my&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;part name=&amp;quot;Parent&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;part name=&amp;quot;Nested&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;type&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Here we can observe that:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
type is referred by a qualified name in import element;&lt;/li&gt;
&lt;li&gt;
type has two forms: simple (see BigDecimal), and other for nested or generic type
(see ArrayList).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
We have made it more consistent in the updated jxom:
&lt;/p&gt;
&lt;p style="PADDING-LEFT: 1em"&gt;
&lt;code&gt;&amp;lt;!-- import java.util.ArrayList; --&amp;gt;&lt;br /&gt;
&amp;lt;import&amp;gt;&lt;br /&gt;
&amp;lt;type name=&amp;quot;ArrayList&amp;quot; package=&amp;quot;java.util&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/import&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- java.util.ArrayList&amp;lt;java.math.BigDecimal&amp;gt; --&amp;gt;&lt;br /&gt;
&amp;lt;type name=&amp;quot;ArrayList&amp;quot; package=&amp;quot;java.util&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;argument&amp;gt;&lt;br /&gt;
&amp;lt;type name=&amp;quot;BigDecimal&amp;quot; package=&amp;quot;java.math&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/argument&amp;gt;&lt;br /&gt;
&amp;lt;/type&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- my.Parent.Nested --&amp;gt;&lt;br /&gt;
&amp;lt;type name=&amp;quot;Nested&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;type name=&amp;quot;Parent&amp;quot; package=&amp;quot;my&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;type&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
We hope that you will not be impacted very much by this fix.
&lt;/p&gt;
&lt;p&gt;
Please refresh Languages XOM from &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=0fdc7420-9599-4b14-979f-5b95ec6df7c9&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2fct.ashx%3fid%3d0fdc7420-9599-4b14-979f-5b95ec6df7c9%26url%3dhttp%253a%252f%252fwww.nesterovsky-bros.com%252fdownload%252flanguages-xom.zip"&gt; languages-xom.zip&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
P.S. we have also included xml schema and xslt api to generate ASPX (see &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=0fdc7420-9599-4b14-979f-5b95ec6df7c9&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2fct.ashx%3fid%3d0fdc7420-9599-4b14-979f-5b95ec6df7c9%26url%3dhttp%253a%252f%252fwww.nesterovsky-bros.com%252fweblog%252f2010%252f06%252f22%252fXsltSerializerForASPXOutput.aspx"&gt; Xslt
serializer for ASPX output&lt;/a&gt;). We, in fact, in our projects, generate aspx documents
with embedded csharpxom, and then pass it through two stage transformation.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=0fdc7420-9599-4b14-979f-5b95ec6df7c9" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,0fdc7420-9599-4b14-979f-5b95ec6df7c9.aspx</comments>
      <category>Announce</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=8b73afea-b89b-417d-b61c-244eb46a8cb0</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,8b73afea-b89b-417d-b61c-244eb46a8cb0.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,8b73afea-b89b-417d-b61c-244eb46a8cb0.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=8b73afea-b89b-417d-b61c-244eb46a8cb0</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In the <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=8b73afea-b89b-417d-b61c-244eb46a8cb0&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2010%2f10%2f09%2fParseCOBOLIntoCobolxom.aspx">previous
post</a> we have announced an <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=8b73afea-b89b-417d-b61c-244eb46a8cb0&amp;url=https%3a%2f%2fincr-parser.svn.sourceforge.net%2fsvnroot%2fincr-parser%2fParser%2fbranches%2fv2.VS2010%2fParser%2fParser.sln">API
to parse a COBOL source into the cobolxom</a>.
</p>
        <p>
We exploited <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=8b73afea-b89b-417d-b61c-244eb46a8cb0&amp;url=http%3a%2f%2fsourceforge.net%2fprojects%2fincr-parser%2f">the
incremental parser</a> to build a grammar xml tree and then were planning to create
an xslt transformation to generate <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=8b73afea-b89b-417d-b61c-244eb46a8cb0&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip">cobolxom</a>.
</p>
        <p>
Now, we would like to declare that such xslt is ready.
</p>
        <p>
At present all standard COBOL constructs are supported, but more tests are required.
Preprocessor support is still in the todo list.
</p>
        <p>
You may peek into an examples of <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=8b73afea-b89b-417d-b61c-244eb46a8cb0&amp;url=https%3a%2f%2fincr-parser.svn.sourceforge.net%2fsvnroot%2fincr-parser%2fParser%2fbranches%2fv2.VS2010%2fParser%2fCobolTest%2fResources%2fKRFM428">COBOL</a>:
</p>
        <iframe src="https://incr-parser.svn.sourceforge.net/svnroot/incr-parser/Parser/branches/v2.VS2010/Parser/CobolTest/Resources/KRFM428" style="width: 100%; height: 15em;" scrolling="auto">
        </iframe>
        <p />
        <p>
          <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=8b73afea-b89b-417d-b61c-244eb46a8cb0&amp;url=https%3a%2f%2fincr-parser.svn.sourceforge.net%2fsvnroot%2fincr-parser%2fParser%2fbranches%2fv2.VS2010%2fParser%2fCobolTest%2fResources%2fcobol.xml">Cobol
grammar</a>:
</p>
        <iframe src="https://incr-parser.svn.sourceforge.net/svnroot/incr-parser/Parser/branches/v2.VS2010/Parser/CobolTest/Resources/cobol.xml" style="width: 100%; height: 15em;" scrolling="auto">
        </iframe>
        <p />
        <p>
And <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=8b73afea-b89b-417d-b61c-244eb46a8cb0&amp;url=https%3a%2f%2fincr-parser.svn.sourceforge.net%2fsvnroot%2fincr-parser%2fParser%2fbranches%2fv2.VS2010%2fParser%2fCobolTest%2fResources%2fcobolxom.xml">cobolxom</a>:
</p>
        <iframe src="https://incr-parser.svn.sourceforge.net/svnroot/incr-parser/Parser/branches/v2.VS2010/Parser/CobolTest/Resources/cobolxom.xml" style="width: 100%; height: 15em;" scrolling="auto">
        </iframe>
        <p>
While we were building a grammar to cobolxom stylesheet we asked ourselves whether
the COBOL parsing could be done entirely in xslt. The answer is yes, so who knows
it might be that we shall turn this task into pure xslt one. :-)
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=8b73afea-b89b-417d-b61c-244eb46a8cb0" />
      </body>
      <title>Parse COBOL into cobolxom, #2</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,8b73afea-b89b-417d-b61c-244eb46a8cb0.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/10/22/ParseCOBOLIntoCobolxom2.aspx</link>
      <pubDate>Fri, 22 Oct 2010 13:24:31 GMT</pubDate>
      <description>&lt;p&gt;
In the &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=8b73afea-b89b-417d-b61c-244eb46a8cb0&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2010%2f10%2f09%2fParseCOBOLIntoCobolxom.aspx"&gt;previous
post&lt;/a&gt; we have announced an &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=8b73afea-b89b-417d-b61c-244eb46a8cb0&amp;amp;url=https%3a%2f%2fincr-parser.svn.sourceforge.net%2fsvnroot%2fincr-parser%2fParser%2fbranches%2fv2.VS2010%2fParser%2fParser.sln"&gt;API
to parse a COBOL source into the cobolxom&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
We exploited &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=8b73afea-b89b-417d-b61c-244eb46a8cb0&amp;amp;url=http%3a%2f%2fsourceforge.net%2fprojects%2fincr-parser%2f"&gt;the
incremental parser&lt;/a&gt; to build a grammar xml tree and then were planning to create
an xslt transformation to generate &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=8b73afea-b89b-417d-b61c-244eb46a8cb0&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip"&gt;cobolxom&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Now, we would like to declare that such xslt is ready.
&lt;/p&gt;
&lt;p&gt;
At present all standard COBOL constructs are supported, but more tests are required.
Preprocessor support is still in the todo list.
&lt;/p&gt;
&lt;p&gt;
You may peek into an examples of &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=8b73afea-b89b-417d-b61c-244eb46a8cb0&amp;amp;url=https%3a%2f%2fincr-parser.svn.sourceforge.net%2fsvnroot%2fincr-parser%2fParser%2fbranches%2fv2.VS2010%2fParser%2fCobolTest%2fResources%2fKRFM428"&gt;COBOL&lt;/a&gt;:
&lt;/p&gt;
&lt;iframe src="https://incr-parser.svn.sourceforge.net/svnroot/incr-parser/Parser/branches/v2.VS2010/Parser/CobolTest/Resources/KRFM428" style="width: 100%; height: 15em;" scrolling="auto"&gt;
&lt;/iframe&gt;
&lt;p /&gt;
&lt;p&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=8b73afea-b89b-417d-b61c-244eb46a8cb0&amp;amp;url=https%3a%2f%2fincr-parser.svn.sourceforge.net%2fsvnroot%2fincr-parser%2fParser%2fbranches%2fv2.VS2010%2fParser%2fCobolTest%2fResources%2fcobol.xml"&gt;Cobol
grammar&lt;/a&gt;:
&lt;/p&gt;
&lt;iframe src="https://incr-parser.svn.sourceforge.net/svnroot/incr-parser/Parser/branches/v2.VS2010/Parser/CobolTest/Resources/cobol.xml" style="width: 100%; height: 15em;" scrolling="auto"&gt;
&lt;/iframe&gt;
&lt;p /&gt;
&lt;p&gt;
And &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=8b73afea-b89b-417d-b61c-244eb46a8cb0&amp;amp;url=https%3a%2f%2fincr-parser.svn.sourceforge.net%2fsvnroot%2fincr-parser%2fParser%2fbranches%2fv2.VS2010%2fParser%2fCobolTest%2fResources%2fcobolxom.xml"&gt;cobolxom&lt;/a&gt;:
&lt;/p&gt;
&lt;iframe src="https://incr-parser.svn.sourceforge.net/svnroot/incr-parser/Parser/branches/v2.VS2010/Parser/CobolTest/Resources/cobolxom.xml" style="width: 100%; height: 15em;" scrolling="auto"&gt;
&lt;/iframe&gt;
&lt;p&gt;
While we were building a grammar to cobolxom stylesheet we asked ourselves whether
the COBOL parsing could be done entirely in xslt. The answer is yes, so who knows
it might be that we shall turn this task into pure xslt one. :&amp;#x2d;)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=8b73afea-b89b-417d-b61c-244eb46a8cb0" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,8b73afea-b89b-417d-b61c-244eb46a8cb0.aspx</comments>
      <category>Announce</category>
      <category>Incremental Parser</category>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=7b0ea49a-5879-4466-bfe8-794f587221fa</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,7b0ea49a-5879-4466-bfe8-794f587221fa.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,7b0ea49a-5879-4466-bfe8-794f587221fa.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=7b0ea49a-5879-4466-bfe8-794f587221fa</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Recently we've seen a code like this:
</p>
        <p style="padding-left: 1em">
          <code> &lt;xsl:variable name="a" as="element()?" select="..."/&gt;<br />
&lt;xsl:variable name="b" as="element()?" select="..."/&gt;<br /><br />
&lt;xsl:apply-templates select="$a"&gt;<br />
  &lt;xsl:with-param name="b" tunnel="yes" as="element()"
select="$b"/&gt;<br />
&lt;/xsl:apply-templates&gt;</code>
        </p>
        <p>
It fails with an error: "An empty sequence is not allowed as the value of parameter
$b".
</p>
        <p>
What is interesting is that the value of $a is an empty sequence, so the code could
potentially work, provided processor evaluated $a first, and decided not to evaluate
xsl:with-param.
</p>
        <p>
Whether the order of evaluation of @select and xsl:with-param is specified by the
standard or it's an implementation defined?
</p>
        <p>
We asked this question on <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=7b0ea49a-5879-4466-bfe8-794f587221fa&amp;url=http%3a%2f%2fthread.gmane.org%2fgmane.text.xml.xsl.general.mulberrytech%2f81773"> xslt
forum</a>, and got the following answer:
</p>
        <p style="padding-left: 1em">
          <code style="font-style: italic;">The specification leaves this implementation-defined.
Since the values of the parameters are the same for every node processed, it's a reasonably
strategy for the processor to evaluate the parameters before knowing how many selected
nodes there are, though I guess <span style="text-decoration: underline;">an even
better strategy would be to do it lazily when the first selected node is found</span>. </code>
        </p>
        <p>
Well, that's an expected answer. This question will probably induce Michael Kay to
introduce a small optimization into the Saxon.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=7b0ea49a-5879-4466-bfe8-794f587221fa" />
      </body>
      <title>What's evaluated first: @select or xsl:with-param?</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,7b0ea49a-5879-4466-bfe8-794f587221fa.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/10/18/WhatsEvaluatedFirstSelectOrXslwithparam.aspx</link>
      <pubDate>Mon, 18 Oct 2010 17:58:51 GMT</pubDate>
      <description>&lt;p&gt;
Recently we&amp;#39;ve seen a code like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; &amp;lt;xsl:variable name=&amp;quot;a&amp;quot; as=&amp;quot;element()?&amp;quot; select=&amp;quot;...&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;xsl:variable name=&amp;quot;b&amp;quot; as=&amp;quot;element()?&amp;quot; select=&amp;quot;...&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;xsl:apply-templates select=&amp;quot;$a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:with-param name=&amp;quot;b&amp;quot; tunnel=&amp;quot;yes&amp;quot; as=&amp;quot;element()&amp;quot;
select=&amp;quot;$b&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:apply-templates&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
It fails with an error: &amp;quot;An empty sequence is not allowed as the value of parameter
$b&amp;quot;.
&lt;/p&gt;
&lt;p&gt;
What is interesting is that the value of $a is an empty sequence, so the code could
potentially work, provided processor evaluated $a first, and decided not to evaluate
xsl:with-param.
&lt;/p&gt;
&lt;p&gt;
Whether the order of evaluation of @select and xsl:with-param is specified by the
standard or it&amp;#39;s an implementation defined?
&lt;/p&gt;
&lt;p&gt;
We asked this question on &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=7b0ea49a-5879-4466-bfe8-794f587221fa&amp;amp;url=http%3a%2f%2fthread.gmane.org%2fgmane.text.xml.xsl.general.mulberrytech%2f81773"&gt; xslt
forum&lt;/a&gt;, and got the following answer:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code style="font-style: italic;"&gt;The specification leaves this implementation-defined.
Since the values of the parameters are the same for every node processed, it's a reasonably
strategy for the processor to evaluate the parameters before knowing how many selected
nodes there are, though I guess &lt;span style="text-decoration: underline;"&gt;an even
better strategy would be to do it lazily when the first selected node is found&lt;/span&gt;. &lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
Well, that's an expected answer. This question will probably induce Michael Kay to
introduce a small optimization into the Saxon.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=7b0ea49a-5879-4466-bfe8-794f587221fa" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,7b0ea49a-5879-4466-bfe8-794f587221fa.aspx</comments>
      <category>Tips and tricks</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=7f371b0a-d51c-4de6-ac88-32536e7d04e0</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,7f371b0a-d51c-4de6-ac88-32536e7d04e0.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,7f371b0a-d51c-4de6-ac88-32536e7d04e0.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=7f371b0a-d51c-4de6-ac88-32536e7d04e0</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Once ago we have created an <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=7f371b0a-d51c-4de6-ac88-32536e7d04e0&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2009%2f03%2f08%2fIncrementalParser.aspx"> incremental
parser</a>, and now when we have decided to load COBOL sources directly into <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=7f371b0a-d51c-4de6-ac88-32536e7d04e0&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2009%2f12%2f27%2fAdditionToXOMFamily.aspx"> cobolxom
(XML Object Model for a COBOL)</a> the parser did the job perfectly.
</p>
        <p>
The good point about incremental parser is that it easily handles COBOL's grammar.
</p>
        <p>
The whole process looks like this:
</p>
        <ol>
          <li>
incremental parser having a COBOL grammar builds a grammar tree;</li>
          <li>
we stream this tree into xml;</li>
          <li>
xslt to transform xml from previous step into <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=7f371b0a-d51c-4de6-ac88-32536e7d04e0&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip">cobolxom</a> (TODO).</li>
        </ol>
        <p>
This is an example of a COBOL:
</p>
        <p style="PADDING-LEFT: 1em">
          <code>IDENTIFICATION DIVISION.<br />
PROGRAM-ID. FACTORIAL RECURSIVE.<br /><br />
DATA DIVISION.<br />
WORKING-STORAGE SECTION.<br />
01 NUMB PIC 9(4) VALUE IS 5.<br />
01 FACT PIC 9(8) VALUE IS 0.<br /><br />
LOCAL-STORAGE SECTION.<br />
01 NUM PIC 9(4).<br /><br />
PROCEDURE DIVISION.<br />
MOVE 'X' TO XXX<br />
MOVE NUMB TO NUM<br /><br />
IF NUMB = 0 THEN<br />
MOVE 1 TO FACT<br />
ELSE<br />
SUBTRACT 1 FROM NUMB<br />
CALL 'FACTORIAL'<br />
MULTIPLY NUM BY FACT<br />
END-IF<br /><br />
DISPLAY NUM '! = ' FACT<br /><br />
GOBACK.<br />
END PROGRAM FACTORIAL.</code>
        </p>
        <p>
And a grammar tree:
</p>
        <p style="PADDING-LEFT: 1em">
          <code>&lt;Program&gt;<br />
&lt;Name data="FACTORIAL"/&gt;<br />
&lt;Recursive/&gt;<br />
&lt;DataDivision&gt;<br />
&lt;WorkingStorageSection&gt;<br />
&lt;Data&gt;<br />
&lt;Level data="01"/&gt;<br />
&lt;Name data="NUMB"/&gt;<br />
&lt;Picture data="9(4)"/&gt;<br />
&lt;Value&gt;<br />
&lt;Numeric data="5"/&gt;<br />
&lt;/Value&gt;<br />
&lt;/Data&gt;<br />
&lt;Data&gt;<br />
&lt;Level data="01"/&gt;<br />
&lt;Name data="FACT"/&gt;<br />
&lt;Picture data="9(8)"/&gt;<br />
&lt;Value&gt;<br />
&lt;Numeric data="0"/&gt;<br />
&lt;/Value&gt;<br />
&lt;/Data&gt;<br />
&lt;/WorkingStorageSection&gt;<br />
&lt;LocalStorageSection&gt;<br />
&lt;Data&gt;<br />
&lt;Level data="01"/&gt;<br />
&lt;Name data="NUM"/&gt;<br />
&lt;Picture data="9(4)"/&gt;<br />
&lt;/Data&gt;<br />
&lt;/LocalStorageSection&gt;<br />
&lt;/DataDivision&gt;<br />
&lt;ProcedureDivision&gt;<br />
&lt;Sentence&gt;<br />
&lt;MoveStatement&gt;<br />
&lt;From&gt;<br />
&lt;String data="'X'"/&gt;<br />
&lt;/From&gt;<br />
&lt;To&gt;<br />
&lt;Identifier&gt;<br />
&lt;DataName data="XXX"/&gt;<br />
&lt;/Identifier&gt;<br />
&lt;/To&gt;<br />
&lt;/MoveStatement&gt;<br />
&lt;MoveStatement&gt;<br />
&lt;From&gt;<br />
&lt;Identifier&gt;<br />
&lt;DataName data="NUMB"/&gt;<br />
&lt;/Identifier&gt;<br />
&lt;/From&gt;<br />
&lt;To&gt;<br />
&lt;Identifier&gt;<br />
&lt;DataName data="NUM"/&gt;<br />
&lt;/Identifier&gt;<br />
&lt;/To&gt;<br />
&lt;/MoveStatement&gt;<br />
&lt;IfStatement&gt;<br />
&lt;Condition&gt;<br />
&lt;Relation&gt;<br />
&lt;Identifier&gt;<br />
&lt;DataName data="NUMB"/&gt;<br />
&lt;/Identifier&gt;<br />
&lt;Equal/&gt;<br />
&lt;Numeric data="0"/&gt;<br />
&lt;/Relation&gt;<br />
&lt;/Condition&gt;<br />
&lt;Then&gt;<br />
&lt;MoveStatement&gt;<br />
&lt;From&gt;<br />
&lt;Numeric data="1"/&gt;<br />
&lt;/From&gt;<br />
&lt;To&gt;<br />
&lt;Identifier&gt;<br />
&lt;DataName data="FACT"/&gt;<br />
&lt;/Identifier&gt;<br />
&lt;/To&gt;<br />
&lt;/MoveStatement&gt;<br />
&lt;/Then&gt;<br />
&lt;Else&gt;<br />
&lt;SubtractStatement&gt;<br />
&lt;Value&gt;<br />
&lt;Numeric data="1"/&gt;<br />
&lt;/Value&gt;<br />
&lt;From&gt;<br />
&lt;Identifier&gt;<br />
&lt;DataName data="NUMB"/&gt;<br />
&lt;/Identifier&gt;<br />
&lt;/From&gt;<br />
&lt;/SubtractStatement&gt;<br />
&lt;CallStatement&gt;<br />
&lt;Name&gt;<br />
&lt;String data="'FACTORIAL'"/&gt;<br />
&lt;/Name&gt;<br />
&lt;/CallStatement&gt;<br />
&lt;MultiplyStatement&gt;<br />
&lt;Value&gt;<br />
&lt;Identifier&gt;<br />
&lt;DataName data="NUM"/&gt;<br />
&lt;/Identifier&gt;<br />
&lt;/Value&gt;<br />
&lt;By&gt;<br />
&lt;Identifier&gt;<br />
&lt;DataName data="FACT"/&gt;<br />
&lt;/Identifier&gt;<br />
&lt;/By&gt;<br />
&lt;/MultiplyStatement&gt;<br />
&lt;/Else&gt;<br />
&lt;/IfStatement&gt;<br />
&lt;DisplayStatement&gt;<br />
&lt;Values&gt;<br />
&lt;Identifier&gt;<br />
&lt;DataName data="NUM"/&gt;<br />
&lt;/Identifier&gt;<br />
&lt;String data="'! = '"/&gt;<br />
&lt;Identifier&gt;<br />
&lt;DataName data="FACT"/&gt;<br />
&lt;/Identifier&gt;<br />
&lt;/Values&gt;<br />
&lt;/DisplayStatement&gt;<br />
&lt;GobackStatement/&gt;<br />
&lt;/Sentence&gt;<br />
&lt;/ProcedureDivision&gt;<br />
&lt;EndName data="FACTORIAL"/&gt;<br />
&lt;/Program&gt;</code>
        </p>
        <p>
The last step is to transform tree into cobolxom is in the TODO list.
</p>
        <p>
We have commited COBOL grammar in the same place at <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=7f371b0a-d51c-4de6-ac88-32536e7d04e0&amp;url=https%3a%2f%2fincr-parser.svn.sourceforge.net%2fsvnroot%2fincr-parser%2fParser%2fbranches%2fv2.VS2010%2fParser%2f"> SourceForge</a> as
it was with XQuery grammar. Solution is now under the VS 2010.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=7f371b0a-d51c-4de6-ac88-32536e7d04e0" />
      </body>
      <title>Parse COBOL into cobolxom</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,7f371b0a-d51c-4de6-ac88-32536e7d04e0.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/10/09/ParseCOBOLIntoCobolxom.aspx</link>
      <pubDate>Sat, 09 Oct 2010 08:26:23 GMT</pubDate>
      <description>  &lt;p&gt;
Once ago we have created an &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=7f371b0a-d51c-4de6-ac88-32536e7d04e0&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2009%2f03%2f08%2fIncrementalParser.aspx"&gt; incremental
parser&lt;/a&gt;, and now when we have decided to load COBOL sources directly into &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=7f371b0a-d51c-4de6-ac88-32536e7d04e0&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2009%2f12%2f27%2fAdditionToXOMFamily.aspx"&gt; cobolxom
(XML Object Model for a COBOL)&lt;/a&gt; the parser did the job perfectly.
&lt;/p&gt;
&lt;p&gt;
The good point about incremental parser is that it easily handles COBOL&amp;#39;s grammar.
&lt;/p&gt;
&lt;p&gt;
The whole process looks like this:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
incremental parser having a COBOL grammar builds a grammar tree;&lt;/li&gt;
&lt;li&gt;
we stream this tree into xml;&lt;/li&gt;
&lt;li&gt;
xslt to transform xml from previous step into &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=7f371b0a-d51c-4de6-ac88-32536e7d04e0&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip"&gt;cobolxom&lt;/a&gt; (TODO).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
This is an example of a COBOL:
&lt;/p&gt;
&lt;p style="PADDING-LEFT: 1em"&gt;
&lt;code&gt;IDENTIFICATION DIVISION.&lt;br /&gt;
PROGRAM-ID. FACTORIAL RECURSIVE.&lt;br /&gt;
&lt;br /&gt;
DATA DIVISION.&lt;br /&gt;
WORKING-STORAGE SECTION.&lt;br /&gt;
01 NUMB PIC 9(4) VALUE IS 5.&lt;br /&gt;
01 FACT PIC 9(8) VALUE IS 0.&lt;br /&gt;
&lt;br /&gt;
LOCAL-STORAGE SECTION.&lt;br /&gt;
01 NUM PIC 9(4).&lt;br /&gt;
&lt;br /&gt;
PROCEDURE DIVISION.&lt;br /&gt;
MOVE &amp;#39;X&amp;#39; TO XXX&lt;br /&gt;
MOVE NUMB TO NUM&lt;br /&gt;
&lt;br /&gt;
IF NUMB = 0 THEN&lt;br /&gt;
MOVE 1 TO FACT&lt;br /&gt;
ELSE&lt;br /&gt;
SUBTRACT 1 FROM NUMB&lt;br /&gt;
CALL &amp;#39;FACTORIAL&amp;#39;&lt;br /&gt;
MULTIPLY NUM BY FACT&lt;br /&gt;
END-IF&lt;br /&gt;
&lt;br /&gt;
DISPLAY NUM &amp;#39;! = &amp;#39; FACT&lt;br /&gt;
&lt;br /&gt;
GOBACK.&lt;br /&gt;
END PROGRAM FACTORIAL.&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
And a grammar tree:
&lt;/p&gt;
&lt;p style="PADDING-LEFT: 1em"&gt;
&lt;code&gt;&amp;lt;Program&amp;gt;&lt;br /&gt;
&amp;lt;Name data=&amp;quot;FACTORIAL&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;Recursive/&amp;gt;&lt;br /&gt;
&amp;lt;DataDivision&amp;gt;&lt;br /&gt;
&amp;lt;WorkingStorageSection&amp;gt;&lt;br /&gt;
&amp;lt;Data&amp;gt;&lt;br /&gt;
&amp;lt;Level data=&amp;quot;01&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;Name data=&amp;quot;NUMB&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;Picture data=&amp;quot;9(4)&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;Value&amp;gt;&lt;br /&gt;
&amp;lt;Numeric data=&amp;quot;5&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/Value&amp;gt;&lt;br /&gt;
&amp;lt;/Data&amp;gt;&lt;br /&gt;
&amp;lt;Data&amp;gt;&lt;br /&gt;
&amp;lt;Level data=&amp;quot;01&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;Name data=&amp;quot;FACT&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;Picture data=&amp;quot;9(8)&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;Value&amp;gt;&lt;br /&gt;
&amp;lt;Numeric data=&amp;quot;0&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/Value&amp;gt;&lt;br /&gt;
&amp;lt;/Data&amp;gt;&lt;br /&gt;
&amp;lt;/WorkingStorageSection&amp;gt;&lt;br /&gt;
&amp;lt;LocalStorageSection&amp;gt;&lt;br /&gt;
&amp;lt;Data&amp;gt;&lt;br /&gt;
&amp;lt;Level data=&amp;quot;01&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;Name data=&amp;quot;NUM&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;Picture data=&amp;quot;9(4)&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/Data&amp;gt;&lt;br /&gt;
&amp;lt;/LocalStorageSection&amp;gt;&lt;br /&gt;
&amp;lt;/DataDivision&amp;gt;&lt;br /&gt;
&amp;lt;ProcedureDivision&amp;gt;&lt;br /&gt;
&amp;lt;Sentence&amp;gt;&lt;br /&gt;
&amp;lt;MoveStatement&amp;gt;&lt;br /&gt;
&amp;lt;From&amp;gt;&lt;br /&gt;
&amp;lt;String data=&amp;quot;&amp;#39;X&amp;#39;&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/From&amp;gt;&lt;br /&gt;
&amp;lt;To&amp;gt;&lt;br /&gt;
&amp;lt;Identifier&amp;gt;&lt;br /&gt;
&amp;lt;DataName data=&amp;quot;XXX&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/Identifier&amp;gt;&lt;br /&gt;
&amp;lt;/To&amp;gt;&lt;br /&gt;
&amp;lt;/MoveStatement&amp;gt;&lt;br /&gt;
&amp;lt;MoveStatement&amp;gt;&lt;br /&gt;
&amp;lt;From&amp;gt;&lt;br /&gt;
&amp;lt;Identifier&amp;gt;&lt;br /&gt;
&amp;lt;DataName data=&amp;quot;NUMB&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/Identifier&amp;gt;&lt;br /&gt;
&amp;lt;/From&amp;gt;&lt;br /&gt;
&amp;lt;To&amp;gt;&lt;br /&gt;
&amp;lt;Identifier&amp;gt;&lt;br /&gt;
&amp;lt;DataName data=&amp;quot;NUM&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/Identifier&amp;gt;&lt;br /&gt;
&amp;lt;/To&amp;gt;&lt;br /&gt;
&amp;lt;/MoveStatement&amp;gt;&lt;br /&gt;
&amp;lt;IfStatement&amp;gt;&lt;br /&gt;
&amp;lt;Condition&amp;gt;&lt;br /&gt;
&amp;lt;Relation&amp;gt;&lt;br /&gt;
&amp;lt;Identifier&amp;gt;&lt;br /&gt;
&amp;lt;DataName data=&amp;quot;NUMB&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/Identifier&amp;gt;&lt;br /&gt;
&amp;lt;Equal/&amp;gt;&lt;br /&gt;
&amp;lt;Numeric data=&amp;quot;0&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/Relation&amp;gt;&lt;br /&gt;
&amp;lt;/Condition&amp;gt;&lt;br /&gt;
&amp;lt;Then&amp;gt;&lt;br /&gt;
&amp;lt;MoveStatement&amp;gt;&lt;br /&gt;
&amp;lt;From&amp;gt;&lt;br /&gt;
&amp;lt;Numeric data=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/From&amp;gt;&lt;br /&gt;
&amp;lt;To&amp;gt;&lt;br /&gt;
&amp;lt;Identifier&amp;gt;&lt;br /&gt;
&amp;lt;DataName data=&amp;quot;FACT&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/Identifier&amp;gt;&lt;br /&gt;
&amp;lt;/To&amp;gt;&lt;br /&gt;
&amp;lt;/MoveStatement&amp;gt;&lt;br /&gt;
&amp;lt;/Then&amp;gt;&lt;br /&gt;
&amp;lt;Else&amp;gt;&lt;br /&gt;
&amp;lt;SubtractStatement&amp;gt;&lt;br /&gt;
&amp;lt;Value&amp;gt;&lt;br /&gt;
&amp;lt;Numeric data=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/Value&amp;gt;&lt;br /&gt;
&amp;lt;From&amp;gt;&lt;br /&gt;
&amp;lt;Identifier&amp;gt;&lt;br /&gt;
&amp;lt;DataName data=&amp;quot;NUMB&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/Identifier&amp;gt;&lt;br /&gt;
&amp;lt;/From&amp;gt;&lt;br /&gt;
&amp;lt;/SubtractStatement&amp;gt;&lt;br /&gt;
&amp;lt;CallStatement&amp;gt;&lt;br /&gt;
&amp;lt;Name&amp;gt;&lt;br /&gt;
&amp;lt;String data=&amp;quot;&amp;#39;FACTORIAL&amp;#39;&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/Name&amp;gt;&lt;br /&gt;
&amp;lt;/CallStatement&amp;gt;&lt;br /&gt;
&amp;lt;MultiplyStatement&amp;gt;&lt;br /&gt;
&amp;lt;Value&amp;gt;&lt;br /&gt;
&amp;lt;Identifier&amp;gt;&lt;br /&gt;
&amp;lt;DataName data=&amp;quot;NUM&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/Identifier&amp;gt;&lt;br /&gt;
&amp;lt;/Value&amp;gt;&lt;br /&gt;
&amp;lt;By&amp;gt;&lt;br /&gt;
&amp;lt;Identifier&amp;gt;&lt;br /&gt;
&amp;lt;DataName data=&amp;quot;FACT&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/Identifier&amp;gt;&lt;br /&gt;
&amp;lt;/By&amp;gt;&lt;br /&gt;
&amp;lt;/MultiplyStatement&amp;gt;&lt;br /&gt;
&amp;lt;/Else&amp;gt;&lt;br /&gt;
&amp;lt;/IfStatement&amp;gt;&lt;br /&gt;
&amp;lt;DisplayStatement&amp;gt;&lt;br /&gt;
&amp;lt;Values&amp;gt;&lt;br /&gt;
&amp;lt;Identifier&amp;gt;&lt;br /&gt;
&amp;lt;DataName data=&amp;quot;NUM&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/Identifier&amp;gt;&lt;br /&gt;
&amp;lt;String data=&amp;quot;&amp;#39;! = &amp;#39;&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;Identifier&amp;gt;&lt;br /&gt;
&amp;lt;DataName data=&amp;quot;FACT&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/Identifier&amp;gt;&lt;br /&gt;
&amp;lt;/Values&amp;gt;&lt;br /&gt;
&amp;lt;/DisplayStatement&amp;gt;&lt;br /&gt;
&amp;lt;GobackStatement/&amp;gt;&lt;br /&gt;
&amp;lt;/Sentence&amp;gt;&lt;br /&gt;
&amp;lt;/ProcedureDivision&amp;gt;&lt;br /&gt;
&amp;lt;EndName data=&amp;quot;FACTORIAL&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/Program&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
The last step is to transform tree into cobolxom is in the TODO list.
&lt;/p&gt;
&lt;p&gt;
We have commited COBOL grammar in the same place at &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=7f371b0a-d51c-4de6-ac88-32536e7d04e0&amp;amp;url=https%3a%2f%2fincr-parser.svn.sourceforge.net%2fsvnroot%2fincr-parser%2fParser%2fbranches%2fv2.VS2010%2fParser%2f"&gt; SourceForge&lt;/a&gt; as
it was with XQuery grammar. Solution is now under the VS 2010.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=7f371b0a-d51c-4de6-ac88-32536e7d04e0" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,7f371b0a-d51c-4de6-ac88-32536e7d04e0.aspx</comments>
      <category>Announce</category>
      <category>Incremental Parser</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=b9741570-43d3-4f65-9576-e91587e2048b</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,b9741570-43d3-4f65-9576-e91587e2048b.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,b9741570-43d3-4f65-9576-e91587e2048b.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=b9741570-43d3-4f65-9576-e91587e2048b</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Suppose you have a timestamp string, and want to check whether it fits to one of the
following formats with leading and trailing spaces:
</p>
        <ul>
          <li>
YYYY-MM-DD-HH.MM.SS.NNNNNN</li>
          <li>
YYYY-MM-DD-HH.MM.SS</li>
          <li>
YYYY-MM-DD</li>
        </ul>
        <p>
We decided to use regex and its capture groups to extract timestamp parts. This left
us with only solution: <code>xsl:analyze-string</code> instruction. It took a couple
more minutes to reach a final solution:
</p>
        <p style="padding-left: 1em">
          <code> &lt;xsl:variable name="parts" as="xs:string*"&gt;<br />
  &lt;xsl:analyze-string select="$value"<br />
    regex="<br />
      ^\s*(\d\d\d\d)-(\d\d)-(\d\d)<br />
      (-(\d\d)\.(\d\d)\.(\d\d)(\.(\d\d\d\d\d\d))?)?\s*$"<br />
    flags="x"&gt;<br />
    &lt;xsl:matching-substring&gt;<br />
      &lt;xsl:sequence select="regex-group(1)"/&gt;<br />
      &lt;xsl:sequence select="regex-group(2)"/&gt;<br />
      &lt;xsl:sequence select="regex-group(3)"/&gt;<br /><br />
      &lt;xsl:sequence select="regex-group(5)"/&gt;<br />
      &lt;xsl:sequence select="regex-group(6)"/&gt;<br />
      &lt;xsl:sequence select="regex-group(7)"/&gt;<br /><br />
      &lt;xsl:sequence select="regex-group(9)"/&gt;<br />
    &lt;/xsl:matching-substring&gt;<br />
  &lt;/xsl:analyze-string&gt;<br />
&lt;/xsl:variable&gt;<br /><br />
&lt;xsl:choose&gt;<br />
  &lt;xsl:when test="exists($parts)"&gt;<br />
    ...<br />
  &lt;/xsl:when&gt;<br />
  &lt;xsl:otherwise&gt;<br />
    ...<br />
  &lt;/xsl:otherwise&gt;<br />
&lt;/xsl:choose&gt;</code>
        </p>
        <p>
How would you solve the problem? Is it the best solution?
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=b9741570-43d3-4f65-9576-e91587e2048b" />
      </body>
      <title>Getting regex captures in xslt</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,b9741570-43d3-4f65-9576-e91587e2048b.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/10/08/GettingRegexCapturesInXslt.aspx</link>
      <pubDate>Fri, 08 Oct 2010 17:37:44 GMT</pubDate>
      <description>&lt;p&gt;
Suppose you have a timestamp string, and want to check whether it fits to one of the
following formats with leading and trailing spaces:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
YYYY-MM-DD-HH.MM.SS.NNNNNN&lt;/li&gt;
&lt;li&gt;
YYYY-MM-DD-HH.MM.SS&lt;/li&gt;
&lt;li&gt;
YYYY-MM-DD&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
We decided to use regex and its capture groups to extract timestamp parts. This left
us with only solution: &lt;code&gt;xsl:analyze-string&lt;/code&gt; instruction. It took a couple
more minutes to reach a final solution:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; &amp;lt;xsl:variable name="parts" as="xs:string*"&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:analyze-string select="$value"&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; regex="&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^\s*(\d\d\d\d)-(\d\d)-(\d\d)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (-(\d\d)\.(\d\d)\.(\d\d)(\.(\d\d\d\d\d\d))?)?\s*$"&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; flags="x"&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:matching-substring&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select="regex-group(1)"/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select="regex-group(2)"/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select="regex-group(3)"/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select="regex-group(5)"/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select="regex-group(6)"/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select="regex-group(7)"/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select="regex-group(9)"/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/xsl:matching-substring&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/xsl:analyze-string&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:variable&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;xsl:choose&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:when test="exists($parts)"&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;lt;/xsl:when&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:otherwise&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;lt;/xsl:otherwise&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:choose&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
How would you solve the problem? Is it the best solution?
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=b9741570-43d3-4f65-9576-e91587e2048b" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,b9741570-43d3-4f65-9576-e91587e2048b.aspx</comments>
      <category>Tips and tricks</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=c4aa3698-e8d1-4448-a523-67373417718a</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,c4aa3698-e8d1-4448-a523-67373417718a.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,c4aa3698-e8d1-4448-a523-67373417718a.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=c4aa3698-e8d1-4448-a523-67373417718a</wfw:commentRss>
      <title>C# XOM Update</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,c4aa3698-e8d1-4448-a523-67373417718a.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/08/04/CXOMUpdate.aspx</link>
      <pubDate>Wed, 04 Aug 2010 14:00:26 GMT</pubDate>
      <description>&lt;p&gt;
We have updated C# XOM (csharpxom) to support C# 4.0 (in fact there are very few changes).
&lt;/p&gt;
&lt;p&gt;
From the grammar perspective this includes:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Dynamic types;&lt;/li&gt;
&lt;li&gt;
Named and optional arguments;&lt;/li&gt;
&lt;li&gt;
Covariance and contravariance of generic parameters for interfaces and delegates.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Dynamic type, C#:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; dynamic dyn = 1;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
C# XOM:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; &amp;lt;var name=&amp;quot;dyn&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;type name=&amp;quot;dynamic&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;initialize&amp;gt;&lt;br /&gt;
&amp;lt;int value=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/initialize&amp;gt;&lt;br /&gt;
&amp;lt;/var&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Named and Optional Arguments, C#:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; int Increment(int value, int increment = 1)&lt;br /&gt;
{&lt;br /&gt;
return value + increment;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Test() 
&lt;br /&gt;
{&lt;br /&gt;
// Regular call.&lt;br /&gt;
Increment(7, 1);&lt;br /&gt;
&lt;br /&gt;
// Call with named parameter.&lt;br /&gt;
Increment(value: 7, increment: 1);&lt;br /&gt;
&lt;br /&gt;
// Call with default.&lt;br /&gt;
Increment(7); 
&lt;br /&gt;
}&lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
C# XOM:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; &amp;lt;method name=&amp;quot;Increment&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;returns&amp;gt;&lt;br /&gt;
&amp;lt;type name=&amp;quot;int&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/returns&amp;gt;&lt;br /&gt;
&amp;lt;parameters&amp;gt;&lt;br /&gt;
&amp;lt;parameter name=&amp;quot;value&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;type name=&amp;quot;int&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/parameter&amp;gt;&lt;br /&gt;
&amp;lt;parameter name=&amp;quot;increment&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;type name=&amp;quot;int&amp;quot;/&amp;gt;&lt;br       &amp;lt;type name=&amp;quot;int&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;initialize&amp;gt;&lt;br /&gt;
&amp;lt;int value=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/initialize&amp;gt;&lt;br /&gt;
&amp;lt;/parameter&amp;gt;&lt;br /&gt;
&amp;lt;/parameters&amp;gt;&lt;br /&gt;
&amp;lt;block&amp;gt;&lt;br /&gt;
&amp;lt;return&amp;gt;&lt;br /&gt;
&amp;lt;add&amp;gt;&lt;br /&gt;
&amp;lt;var-ref name=&amp;quot;value&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;var-ref name=&amp;quot;increment&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/add&amp;gt;&lt;br /&gt;
&amp;lt;/return&amp;gt; 
&lt;br /&gt;
&amp;lt;/block&amp;gt;&lt;br /&gt;
&amp;lt;/method&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;method name=&amp;quot;Test&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;block&amp;gt;&lt;br /&gt;
&amp;lt;expression&amp;gt;&lt;br /&gt;
&amp;lt;comment&amp;gt;Regular call.&amp;lt;/comment&amp;gt;&lt;br /&gt;
&amp;lt;invoke&amp;gt;&lt;br /&gt;
&amp;lt;method-ref name=&amp;quot;Increment&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;arguments&amp;gt;&lt;br /&gt;
&amp;lt;int value=&amp;quot;7&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;int value=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/arguments&amp;gt;&lt;br /&gt;
&amp;lt;/invoke&amp;gt;&lt;br /&gt;
&amp;lt;/expression&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;expression&amp;gt;&lt;br /&gt;
&amp;lt;comment&amp;gt;Call with named parameter.&amp;lt;/comment&amp;gt;&lt;br /&gt;
&amp;lt;invoke&amp;gt;&lt;br /&gt;
&amp;lt;method-ref name=&amp;quot;Increment&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;arguments&amp;gt;&lt;br /&gt;
&amp;lt;argument name=&amp;quot;value&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;int value=&amp;quot;7&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/argument&amp;gt;&lt;br /&gt;
&amp;lt;argument name=&amp;quot;increment&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;int value=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/argument&amp;gt;&lt;br /&gt;
&amp;lt;/arguments&amp;gt;&lt;br /&gt;
&amp;lt;/invoke&amp;gt;&lt;br /&gt;
&amp;lt;/expression&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;expression&amp;gt;&lt;br /&gt;
&amp;lt;comment&amp;gt;Call with default.&amp;lt;/comment&amp;gt;&lt;br /&gt;
&amp;lt;invoke&amp;gt;&lt;br /&gt;
&amp;lt;method-ref name=&amp;quot;Increment&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;arguments&amp;gt;&lt;br /&gt;
&amp;lt;int value=&amp;quot;7&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/arguments&amp;gt;&lt;br /&gt;
&amp;lt;/invoke&amp;gt;&lt;br /&gt;
&amp;lt;/expression&amp;gt;&lt;br /&gt;
&amp;lt;/block&amp;gt; 
&lt;br /&gt;
&amp;lt;/method&amp;gt;&lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
Covariance and contravariance, C#:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;public interface Variance&amp;lt;in T, out P, Q&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
P X(T t); 
&lt;br /&gt;
}&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
C# XOM:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; &amp;lt;interface access=&amp;quot;public&amp;quot; name=&amp;quot;Variance&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;type-parameters&amp;gt;&lt;br /&gt;
&amp;lt;type-parameter name=&amp;quot;T&amp;quot; variance=&amp;quot;in&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;type-parameter name=&amp;quot;P&amp;quot; variance=&amp;quot;out&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;type-parameter name=&amp;quot;Q&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/type-parameters&amp;gt;&lt;br /&gt;
&amp;lt;method name=&amp;quot;X&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;returns&amp;gt;&lt;br /&gt;
&amp;lt;type name=&amp;quot;P&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/returns&amp;gt;&lt;br /&gt;
&amp;lt;parameters&amp;gt;&lt;br /&gt;
&amp;lt;parameter name=&amp;quot;t&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;type name=&amp;quot;T&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/parameter&amp;gt;&lt;br /&gt;
&amp;lt;/parameters&amp;gt;&lt;br /&gt;
&amp;lt;/method&amp;gt; 
&lt;br /&gt;
&amp;lt;/interface&amp;gt;&lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
Other cosmetic fixes were also introduced into Java XOM (jxom), COBOL XOM (cobolxom),
and into sql XOM (sqlxom).
&lt;/p&gt;
&lt;p&gt;
The new version is found at &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=c4aa3698-e8d1-4448-a523-67373417718a&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip"&gt; languages-xom.zip&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
See also: &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=c4aa3698-e8d1-4448-a523-67373417718a&amp;amp;url=http%3a%2f%2fmsdn.microsoft.com%2fen-us%2flibrary%2fbb383815.aspx"&gt;What&amp;#39;s
New in Visual C# 2010&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=c4aa3698-e8d1-4448-a523-67373417718a" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,c4aa3698-e8d1-4448-a523-67373417718a.aspx</comments>
      <category>Announce</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=1bf907eb-8134-4eeb-9bb9-3cd7e82ee8eb</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,1bf907eb-8134-4eeb-9bb9-3cd7e82ee8eb.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,1bf907eb-8134-4eeb-9bb9-3cd7e82ee8eb.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=1bf907eb-8134-4eeb-9bb9-3cd7e82ee8eb</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We have run into another xslt bug, which depends on several independent circumstances
and often behaves differently being observed. That's clearly a Heisenbug.
</p>
        <p>
Xslt designers failed to realize that a syntactic suggar they introduce into xpath
can turn into obscure bugs. Well, it's easy to be wise afterwards...
</p>
        <p>
To the point.
</p>
        <p>
Consider you have a sequence consisting of text nodes and elements, and now you want
to "normalize" this sequence wrapping adjacent text nodes into separate
elements. The following stylesheet is supposed to do the work:
</p>
        <p style="padding-left: 1em;">
          <code style="direction: ltr">&lt;xsl:stylesheet version="2.0"<br />
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
<br />
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
<br />
  xmlns:t="http://www.nesterovsky-bros.com/xslt/this" 
<br />
  exclude-result-prefixes="xs t"&gt;<br /><br />
  &lt;xsl:template match="/"&gt; 
<br />
    &lt;xsl:variable name="nodes" as="node()*"&gt;<br />
      &lt;xsl:text&gt;Hello, &lt;/xsl:text&gt;<br />
      &lt;string value="World"/&gt;<br />
      &lt;xsl:text&gt;! &lt;/xsl:text&gt;<br />
      &lt;xsl:text&gt;Well, &lt;/xsl:text&gt;<br />
      &lt;string value="hello"/&gt;<br />
      &lt;xsl:text&gt;, if not joking!&lt;/xsl:text&gt;<br />
    &lt;/xsl:variable&gt;<br />
 <br />
    &lt;result&gt;<br />
      &lt;xsl:sequence select="t:normalize($nodes)"/&gt;<br />
    &lt;/result&gt;<br />
  &lt;/xsl:template&gt;<br /><br />
  &lt;xsl:function name="t:normalize" as="node()*"&gt;<br />
    &lt;xsl:param name="nodes" as="node()*"/&gt;<br /><br />
    &lt;xsl:for-each-group select="$nodes" group-starting-with="*"&gt;<br />
      &lt;xsl:variable name="string" as="element()?"
select="self::string"/&gt;<br />
      &lt;xsl:variable name="texts" as="node()*"<br />
        select="current-group() except $string"/&gt;<br /><br />
      &lt;xsl:sequence select="$string"/&gt;<br /><br />
      &lt;xsl:if test="exists($texts)"&gt;<br />
        &lt;string value="{string-join($texts,
'')}"/&gt;<br />
      &lt;/xsl:if&gt;<br />
    &lt;/xsl:for-each-group&gt;<br />
  &lt;/xsl:function&gt;<br /><br />
&lt;/xsl:stylesheet&gt;</code>
        </p>
        <p>
We're expecting the following output:
</p>
        <p style="padding-left: 1em">
          <code>&lt;result&gt;<br />
  &lt;string value="Hello, "/&gt;<br />
  &lt;string value="World"/&gt;<br />
  &lt;string value="! Well, "/&gt;<br />
  &lt;string value="hello"/&gt;<br />
  &lt;string value=", if not joking!"/&gt;<br />
&lt;/result&gt;</code>
        </p>
        <p>
But often we're getting other results, like:
</p>
        <p style="padding-left: 1em">
          <code>&lt;result&gt;<br />
  &lt;string value="Hello, "/&gt;<br />
  &lt;string value="World"/&gt;<br />
  &lt;string value="Well, ! "/&gt;<br />
  &lt;string value="hello"/&gt;<br />
  &lt;string value=", if not joking!"/&gt;<br />
&lt;/result&gt;</code>
        </p>
        <p>
Such output may seriously confuse, unless you will recall the rule for the xpath <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=1bf907eb-8134-4eeb-9bb9-3cd7e82ee8eb&amp;url=http%3a%2f%2fwww.w3.org%2fTR%2fxpath20%2f%23doc-xpath-IntersectExceptExpr"><code>except</code> operator</a>:
</p>
        <p style="padding-left: 1em; font-style: italic;">
The except operator takes two node sequences as operands and returns a sequence containing
all the nodes that occur in the first operand but not in the second operand.<br /><br />
... these operators eliminate duplicate nodes from their result sequences based on
node identity. <span class="xpath">The resulting sequence is returned in <a href="#dt-document-order" title="document order">document
order</a>..<br /><br />
...<br />
The relative order of nodes in distinct trees is stable but implementation-dependent
</span></p>
        <p>
These words mean that result sequence may be very different from original sequence.
</p>
        <p>
In contrast, if we change <code>$text</code> definition to:
</p>
        <p style="padding-left: 1em">
          <code>&lt;xsl:variable name="texts" as="node()*"<br />
  select="current-group()[not(. is $string)]"/&gt;</code>
        </p>
        <p>
then the result becomes stable, but less clear. 
</p>
        <p>
See also <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=1bf907eb-8134-4eeb-9bb9-3cd7e82ee8eb&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2010%2f04%2f02%2fXsltHeisenbug.aspx"> Xslt
Heisenbug</a></p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=1bf907eb-8134-4eeb-9bb9-3cd7e82ee8eb" />
      </body>
      <title>Another xslt Heisenbug</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,1bf907eb-8134-4eeb-9bb9-3cd7e82ee8eb.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/07/15/AnotherXsltHeisenbug.aspx</link>
      <pubDate>Thu, 15 Jul 2010 08:22:13 GMT</pubDate>
      <description>&lt;p&gt;
We have run into another xslt bug, which depends on several independent circumstances
and often behaves differently being observed. That&amp;#39;s clearly a Heisenbug.
&lt;/p&gt;
&lt;p&gt;
Xslt designers failed to realize that a syntactic suggar they introduce into xpath
can turn into obscure bugs. Well, it&amp;#39;s easy to be wise afterwards...
&lt;/p&gt;
&lt;p&gt;
To the point.
&lt;/p&gt;
&lt;p&gt;
Consider you have a sequence consisting of text nodes and elements, and now you want
to &amp;quot;normalize&amp;quot; this sequence wrapping adjacent text nodes into separate
elements. The following stylesheet is supposed to do the work:
&lt;/p&gt;
&lt;p style="padding-left: 1em;"&gt;
&lt;code style="direction: ltr"&gt;&amp;lt;xsl:stylesheet version=&amp;quot;2.0&amp;quot;&lt;br /&gt;
&amp;nbsp; xmlns:xsl=&amp;quot;http://www.w3.org/1999/XSL/Transform&amp;quot; 
&lt;br /&gt;
&amp;nbsp; xmlns:xs=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot; 
&lt;br /&gt;
&amp;nbsp; xmlns:t=&amp;quot;http://www.nesterovsky-bros.com/xslt/this&amp;quot; 
&lt;br /&gt;
&amp;nbsp; exclude-result-prefixes=&amp;quot;xs t&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:template match=&amp;quot;/&amp;quot;&amp;gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:variable name=&amp;quot;nodes&amp;quot; as=&amp;quot;node()*&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:text&amp;gt;Hello, &amp;lt;/xsl:text&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string value=&amp;quot;World&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:text&amp;gt;! &amp;lt;/xsl:text&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:text&amp;gt;Well, &amp;lt;/xsl:text&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string value=&amp;quot;hello&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:text&amp;gt;, if not joking!&amp;lt;/xsl:text&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/xsl:variable&amp;gt;&lt;br /&gt;
&amp;nbsp;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;result&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select=&amp;quot;t:normalize($nodes)&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/result&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:function name=&amp;quot;t:normalize&amp;quot; as=&amp;quot;node()*&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:param name=&amp;quot;nodes&amp;quot; as=&amp;quot;node()*&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:for-each-group select=&amp;quot;$nodes&amp;quot; group-starting-with=&amp;quot;*&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:variable name=&amp;quot;string&amp;quot; as=&amp;quot;element()?&amp;quot;
select=&amp;quot;self::string&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:variable name=&amp;quot;texts&amp;quot; as=&amp;quot;node()*&amp;quot;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select=&amp;quot;current-group() except $string&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select=&amp;quot;$string&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:if test=&amp;quot;exists($texts)&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string value=&amp;quot;{string-join($texts,
&amp;#39;&amp;#39;)}&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/xsl:if&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/xsl:for-each-group&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/xsl:function&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/xsl:stylesheet&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
We&amp;#39;re expecting the following output:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&amp;lt;result&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;string value=&amp;quot;Hello, &amp;quot;/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;string value=&amp;quot;World&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;lt;string value=&amp;quot;! Well, &amp;quot;/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;string value=&amp;quot;hello&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;lt;string value=&amp;quot;, if not joking!&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/result&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
But often we&amp;#39;re getting other results, like:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&amp;lt;result&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;string value=&amp;quot;Hello, &amp;quot;/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;string value=&amp;quot;World&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;string value=&amp;quot;Well, ! &amp;quot;/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;string value=&amp;quot;hello&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;string value=&amp;quot;, if not joking!&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/result&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Such output may seriously confuse, unless you will recall the rule for the xpath &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=1bf907eb-8134-4eeb-9bb9-3cd7e82ee8eb&amp;amp;url=http%3a%2f%2fwww.w3.org%2fTR%2fxpath20%2f%23doc-xpath-IntersectExceptExpr"&gt; &lt;code&gt;except&lt;/code&gt; operator&lt;/a&gt;:
&lt;/p&gt;
&lt;p style="padding-left: 1em; font-style: italic;"&gt;
The except operator takes two node sequences as operands and returns a sequence containing
all the nodes that occur in the first operand but not in the second operand.&lt;br /&gt;
&lt;br /&gt;
... these operators eliminate duplicate nodes from their result sequences based on
node identity. &lt;span class="xpath"&gt;The resulting sequence is returned in &lt;a href="#dt-document-order" title="document order"&gt;document
order&lt;/a&gt;..&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
The relative order of nodes in distinct trees is stable but implementation-dependent
&lt;/p&gt;
&lt;p&gt;
These words mean that result sequence may be very different from original sequence.
&lt;/p&gt;
&lt;p&gt;
In contrast, if we change &lt;code&gt;$text&lt;/code&gt; definition to:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&amp;lt;xsl:variable name=&amp;quot;texts&amp;quot; as=&amp;quot;node()*&amp;quot;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;select=&amp;quot;current-group()[not(. is $string)]&amp;quot;/&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
then the result becomes stable, but less clear. 
&lt;/p&gt;
&lt;p&gt;
See also &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=1bf907eb-8134-4eeb-9bb9-3cd7e82ee8eb&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2010%2f04%2f02%2fXsltHeisenbug.aspx"&gt; Xslt
Heisenbug&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=1bf907eb-8134-4eeb-9bb9-3cd7e82ee8eb" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,1bf907eb-8134-4eeb-9bb9-3cd7e82ee8eb.aspx</comments>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=bd5a8c26-7bf7-4103-8f45-02e0a970efec</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,bd5a8c26-7bf7-4103-8f45-02e0a970efec.aspx</pingback:target>
      <dc:creator>Arthur Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,bd5a8c26-7bf7-4103-8f45-02e0a970efec.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=bd5a8c26-7bf7-4103-8f45-02e0a970efec</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Recently we were raising a <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=bd5a8c26-7bf7-4103-8f45-02e0a970efec&amp;url=http%3a%2f%2fthread.gmane.org%2fgmane.text.xml.xsl.general.mulberrytech%2f80506">question
about serialization of ASPX output in xslt</a>.
</p>
        <p>
The question went like this:
</p>
        <p style="PADDING-LEFT: 1em; FONT-STYLE: italic">
What's the recommended way of ASPX page generation?<br />
E.g.:<br /><br />
------------------------<br />
 &lt;%@ Page AutoEventWireup="true"<br />
   CodeBehind="CurMainMenuP.aspx.cs"<br />
   EnableSessionState="True"<br />
   Inherits="Currency.CurMainMenuP"<br />
   Language="C#"<br />
   MaintainScrollPositionOnPostback="True"<br />
   MasterPageFile="Screen.Master" %&gt;<br /><br />
&lt;asp:Content ID="Content1" runat="server" ContentPlaceHolderID="Title"&gt;CUR_MAIN_MENU_P&lt;/asp:Content&gt;<br /><br />
&lt;asp:Content ID="Content2" runat="server" ContentPlaceHolderID="Content"&gt;<br />
  &lt;span id="id1222146581" runat="server" 
<br />
    class="inputField system UpperCase" enableviewstate="false"&gt;<br />
    &lt;%# Dialog.Global.TranCode %&gt;<br />
  &lt;/span&gt;<br />
  ...<br />
------------------------<br /><br />
Notice aspx page directives, data binding expessions, and prefixed tag names without
namespace declarations.
</p>
        <p>
There was a whole range of expected answers. We, however, looked whether somebody
have already dealed with the task and has a ready solution at hands.
</p>
        <p>
In general it seems that xslt community is very angry about ASPX: both format and
technology. Well, put this aside.
</p>
        <p>
The task of producing ASPX, which is <b>almost</b> xml, is not solvable when you're
staying with pure xml serializer. Xslt's <code><a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=bd5a8c26-7bf7-4103-8f45-02e0a970efec&amp;url=http%3a%2f%2fwww.w3.org%2fTR%2fxslt20%2f%23element-character-map">xsl:character-map</a></code> does
not work at all. In fact it looks as a childish attempt to address the problem, as
it does not support character escapes but only grabs characters and substitutes them
with strings.
</p>
        <p>
We have decided to create ASPX serializer API producing required output text. This
way you use <code>&lt;xsl:output method="text"/&gt;</code> to generate ASPX pages.
</p>
        <p>
With this goal in mind we have defined a little xml schema to describe ASPX irregularities
in xml form. These are:
</p>
        <ul>
          <li>
            <code>&lt;xs:element name="declared-prefix"&gt;</code> - to describe known prefixes,
which should not be declared; 
</li>
          <li>
            <code>&lt;xs:element name="directive"&gt;</code> - to describe directives like &lt;%@
Page %&gt;; 
</li>
          <li>
            <code>&lt;xs:element name="content"&gt;</code> - a transparent content wrapper; 
</li>
          <li>
            <code>&lt;xs:element name="entity"&gt;</code> - to issue xml entity; 
</li>
          <li>
            <code>&lt;xs:element name="expression"&gt;</code> - to describe aspx expression like
&lt;%# Eval("A") %&gt;; 
</li>
          <li>
            <code>&lt;xs:element name="attribute"&gt;</code> - to describe an attribute of the
parent element. 
</li>
        </ul>
        <p>
This approach greately simplified for us an ASPX generation process.
</p>
        <p>
The API includes:
</p>
        <ul>
          <li>
            <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=bd5a8c26-7bf7-4103-8f45-02e0a970efec&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fasp.net%2faspx.xsd">aspx.xsd</a> -
an xml schema for the ASPX elements; 
</li>
          <li>
            <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=bd5a8c26-7bf7-4103-8f45-02e0a970efec&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fasp.net%2faspx-serializer.xslt">aspx-serializer.xslt</a> -
a serializer API; 
</li>
          <li>
            <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=bd5a8c26-7bf7-4103-8f45-02e0a970efec&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fasp.net%2faspx-test.xslt">aspx-test.xslt</a> -
a test stylesheet (any xml input is used). 
</li>
        </ul>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=bd5a8c26-7bf7-4103-8f45-02e0a970efec" />
      </body>
      <title>Xslt serializer for ASPX output</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,bd5a8c26-7bf7-4103-8f45-02e0a970efec.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/06/22/XsltSerializerForASPXOutput.aspx</link>
      <pubDate>Tue, 22 Jun 2010 10:25:41 GMT</pubDate>
      <description>&lt;p&gt;
Recently we were raising a &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=bd5a8c26-7bf7-4103-8f45-02e0a970efec&amp;amp;url=http%3a%2f%2fthread.gmane.org%2fgmane.text.xml.xsl.general.mulberrytech%2f80506"&gt;question
about serialization of ASPX output in xslt&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
The question went like this:
&lt;/p&gt;
&lt;p style="PADDING-LEFT: 1em; FONT-STYLE: italic"&gt;
What's the recommended way of ASPX page generation?&lt;br&gt;
E.g.:&lt;br&gt;
&lt;br&gt;
------------------------&lt;br&gt;
&amp;nbsp;&amp;lt;%@ Page AutoEventWireup="true"&lt;br&gt;
&amp;nbsp;&amp;nbsp; CodeBehind="CurMainMenuP.aspx.cs"&lt;br&gt;
&amp;nbsp;&amp;nbsp; EnableSessionState="True"&lt;br&gt;
&amp;nbsp;&amp;nbsp; Inherits="Currency.CurMainMenuP"&lt;br&gt;
&amp;nbsp;&amp;nbsp; Language="C#"&lt;br&gt;
&amp;nbsp;&amp;nbsp; MaintainScrollPositionOnPostback="True"&lt;br&gt;
&amp;nbsp;&amp;nbsp; MasterPageFile="Screen.Master" %&amp;gt;&lt;br&gt;
&lt;br&gt;
&amp;lt;asp:Content ID="Content1" runat="server" ContentPlaceHolderID="Title"&amp;gt;CUR_MAIN_MENU_P&amp;lt;/asp:Content&amp;gt;&lt;br&gt;
&lt;br&gt;
&amp;lt;asp:Content ID="Content2" runat="server" ContentPlaceHolderID="Content"&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;span id="id1222146581" runat="server" 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; class="inputField system UpperCase" enableviewstate="false"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;%# Dialog.Global.TranCode %&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;/span&amp;gt;&lt;br&gt;
&amp;nbsp; ...&lt;br&gt;
------------------------&lt;br&gt;
&lt;br&gt;
Notice aspx page directives, data binding expessions, and prefixed tag names without
namespace declarations.
&lt;/p&gt;
&lt;p&gt;
There was a whole range of expected answers. We, however, looked whether somebody
have already dealed with the task and has a ready solution at hands.
&lt;/p&gt;
&lt;p&gt;
In general it seems that xslt community is very angry about ASPX: both format and
technology. Well, put this aside.
&lt;/p&gt;
&lt;p&gt;
The task of producing ASPX, which is &lt;b&gt;almost&lt;/b&gt; xml, is not solvable when you're
staying with pure xml serializer. Xslt's &lt;code&gt;&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=bd5a8c26-7bf7-4103-8f45-02e0a970efec&amp;amp;url=http%3a%2f%2fwww.w3.org%2fTR%2fxslt20%2f%23element-character-map"&gt;xsl:character-map&lt;/a&gt;&lt;/code&gt; does
not work at all. In fact it looks as a childish attempt to address the problem, as
it does not support character escapes but only grabs characters and substitutes them
with strings.
&lt;/p&gt;
&lt;p&gt;
We have decided to create ASPX serializer API producing required output text. This
way you use &lt;code&gt;&amp;lt;xsl:output method="text"/&amp;gt;&lt;/code&gt; to generate ASPX pages.
&lt;/p&gt;
&lt;p&gt;
With this goal in mind we have defined a little xml schema to describe ASPX irregularities
in xml form. These are:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;xs:element name="declared-prefix"&amp;gt;&lt;/code&gt; - to describe known prefixes,
which should not be declared; 
&lt;li&gt;
&lt;code&gt;&amp;lt;xs:element name="directive"&amp;gt;&lt;/code&gt; - to describe directives like &amp;lt;%@
Page %&amp;gt;; 
&lt;li&gt;
&lt;code&gt;&amp;lt;xs:element name="content"&amp;gt;&lt;/code&gt; - a transparent content wrapper; 
&lt;li&gt;
&lt;code&gt;&amp;lt;xs:element name="entity"&amp;gt;&lt;/code&gt; - to issue xml entity; 
&lt;li&gt;
&lt;code&gt;&amp;lt;xs:element name="expression"&amp;gt;&lt;/code&gt; - to describe aspx expression like
&amp;lt;%# Eval("A") %&amp;gt;; 
&lt;li&gt;
&lt;code&gt;&amp;lt;xs:element name="attribute"&amp;gt;&lt;/code&gt; - to describe an attribute of the
parent element. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
This approach greately simplified for us an ASPX generation process.
&lt;/p&gt;
&lt;p&gt;
The API includes:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=bd5a8c26-7bf7-4103-8f45-02e0a970efec&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fasp.net%2faspx.xsd"&gt;aspx.xsd&lt;/a&gt; -
an xml schema for the ASPX elements; 
&lt;li&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=bd5a8c26-7bf7-4103-8f45-02e0a970efec&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fasp.net%2faspx-serializer.xslt"&gt;aspx-serializer.xslt&lt;/a&gt; -
a serializer API; 
&lt;li&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=bd5a8c26-7bf7-4103-8f45-02e0a970efec&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fasp.net%2faspx-test.xslt"&gt;aspx-test.xslt&lt;/a&gt; -
a test stylesheet (any xml input is used). 
&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=bd5a8c26-7bf7-4103-8f45-02e0a970efec" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,bd5a8c26-7bf7-4103-8f45-02e0a970efec.aspx</comments>
      <category>Announce</category>
      <category>ASP.NET</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We have implemented report parser in C#. Bacause things are spinned around C#, a schema
definition is changed.
</p>
        <p>
We have started from classes defining a report definition tree, annotated these classes
for xml serialization, and, finally, produced xml schema for such tree. So, at present,
it is not an xml schema with annotations but a separate xml schema.
</p>
        <p>
In addition we have defined APIs:
</p>
        <ul>
          <li>
to enumerate report data (having report definition and report data one can get <code>IEnumerable&lt;ViewValue&gt;</code> to
iterate report data in structured form);</li>
          <li>
to read report through <code>XmlReader</code>, which allows, for example, to have
report as input for an xslt tranformation.</li>
          <li>
to write report directly into <code>XmlWriter</code>.</li>
        </ul>
        <p>
An example of report definition as C# code is: <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2fct.ashx%3fid%3d4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b%26url%3dhttp%253a%252f%252fwww.nesterovsky-bros.com%252fdownload%252freports%252fMyReport.cs.txt"> MyReport.cs</a>.
The very same report definition but serialized into xml is <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2fct.ashx%3fid%3d4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b%26url%3dhttp%253a%252f%252fwww.nesterovsky-bros.com%252fdownload%252freports%252fmy-report.xml"> my-report.xml</a>.
A generated xml schema for a report definition is: <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2fct.ashx%3fid%3d4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b%26url%3dhttp%253a%252f%252fwww.nesterovsky-bros.com%252fdownload%252freports%252fschema0.xsd"> schema0.xsd</a>.
</p>
        <p>
The good point about this solution is that it's already flexible enough to describe
every report layout we have at hands, and it's extendable. Our measurments show
that report parsing is extremely fast and have very small memory footprint due to
forward only nature of report definitions.
</p>
        <p>
From the design point of view report definition is a view of original text data with
view info attached.
</p>
        <p>
At present we have defined following views:
</p>
        <ul>
          <li>
Element - a named view to generate output from a content view;</li>
          <li>
 Content - a view to aggregate other views together;</li>
          <li>
Choice - a view to produce output from one of content views;</li>
          <li>
Sequence - a view to sequence input view by key expressions, and to attach an index
to each sequence item;</li>
          <li>
Iterator - a view to generate output from input view while some condition is true,
and to attach an iteration index to each part of output view;</li>
          <li>
Page - a view to remove page headers and footers in the input view, and to attach
an index to each page;</li>
          <li>
Compute - a named view to produce result of evaluation of expression as output view;</li>
          <li>
 Data - a named view to produce output value from some bounds of input view,
and optionally to convert, validate and format the value.</li>
        </ul>
        <p>
To specify details of definitions there are:
</p>
        <ul>
          <li>
expressions to deal with integers: <code>Add</code>, <code>Div</code>, <code> Integer</code>, <code>MatchProperty</code>, <code>Max</code>, <code>Min</code>, <code>Mod</code>, <code>Mul</code>, <code>Neg</code>, <code>Null</code>, <code> Sub</code>, <code>VariableRef</code>, <code>ViewProperty</code>, <code>Case</code>; 
</li>
          <li>
conditions to deal with booleans: <code>And</code>, <code>EQ</code>, <code>GE</code>, <code>GT</code>, <code>IsMatch</code>, <code>LE</code>, <code>LT</code>, <code> NE</code>, <code>Not</code>, <code>Or</code>.</li>
        </ul>
        <p>
At present there is no a specification of a report definitions. Probably, it's
the most complex part to create such a spec for a user without deep knowledge. At
present, our idea is that one should use xml schema (we should polish generated schema)
for the report definition and schema aware editor to build report definitions. That's
very robust approach working perfectly with <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2fct.ashx%3fid%3d4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b%26url%3dhttp%253a%252f%252fwww.nesterovsky-bros.com%252fdownload%252flanguages-xom.zip"> languages
xom</a>.
</p>
        <p>
C# sources can be found at: <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2fct.ashx%3fid%3d4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b%26url%3dhttp%253a%252f%252fwww.nesterovsky-bros.com%252fdownload%252freports%252fReportLayout.zip"> ReportLayout.zip</a> including
report definition classes and a sample report.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b" />
      </body>
      <title>Parsing Reports V2, C#</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/05/14/ParsingReportsV2C.aspx</link>
      <pubDate>Fri, 14 May 2010 12:45:42 GMT</pubDate>
      <description>  &lt;p&gt;
We have implemented report parser in C#. Bacause things are spinned around C#, a schema
definition is changed.
&lt;/p&gt;
&lt;p&gt;
We have started from classes defining a report definition tree, annotated these classes
for xml serialization, and, finally, produced xml schema for such tree. So, at present,
it is not an xml schema with annotations but a separate xml schema.
&lt;/p&gt;
&lt;p&gt;
In addition we have defined APIs:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
to enumerate report data (having report definition and report data one can get &lt;code&gt;IEnumerable&amp;lt;ViewValue&amp;gt;&lt;/code&gt; to
iterate report data in structured form);&lt;/li&gt;
&lt;li&gt;
to read report through &lt;code&gt;XmlReader&lt;/code&gt;, which allows, for example, to have
report as input for an xslt tranformation.&lt;/li&gt;
&lt;li&gt;
to write report directly into &lt;code&gt;XmlWriter&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
An example of report definition as C# code is: &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2fct.ashx%3fid%3d4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b%26url%3dhttp%253a%252f%252fwww.nesterovsky-bros.com%252fdownload%252freports%252fMyReport.cs.txt"&gt; MyReport.cs&lt;/a&gt;.
The very same report definition but serialized into xml is &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2fct.ashx%3fid%3d4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b%26url%3dhttp%253a%252f%252fwww.nesterovsky-bros.com%252fdownload%252freports%252fmy-report.xml"&gt; my-report.xml&lt;/a&gt;.
A generated xml schema for a report definition is: &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2fct.ashx%3fid%3d4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b%26url%3dhttp%253a%252f%252fwww.nesterovsky-bros.com%252fdownload%252freports%252fschema0.xsd"&gt; schema0.xsd&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
The good point about this solution is that it&amp;#39;s already flexible enough to describe
every report layout we have at hands, and it&amp;#39;s extendable. Our measurments show
that report parsing is extremely fast and have very small memory footprint due to
forward only nature of report definitions.
&lt;/p&gt;
&lt;p&gt;
From the design point of view report definition is a view of original text data with
view info attached.
&lt;/p&gt;
&lt;p&gt;
At present we have defined following views:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Element - a named view to generate output from a content view;&lt;/li&gt;
&lt;li&gt;
&amp;nbsp;Content - a view to aggregate other views together;&lt;/li&gt;
&lt;li&gt;
Choice - a view to produce output from one of content views;&lt;/li&gt;
&lt;li&gt;
Sequence - a view to sequence input view by key expressions, and to attach an index
to each sequence item;&lt;/li&gt;
&lt;li&gt;
Iterator - a view to generate output from input view while some condition is true,
and to attach an iteration index to each part of output view;&lt;/li&gt;
&lt;li&gt;
Page - a view to remove page headers and footers in the input view, and to attach
an index to each page;&lt;/li&gt;
&lt;li&gt;
Compute - a named view to produce result of evaluation of expression as output view;&lt;/li&gt;
&lt;li&gt;
&amp;nbsp;Data - a named view to produce output value from some bounds of input view,
and optionally to convert, validate and format the value.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
To specify details of definitions there are:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
expressions to deal with integers: &lt;code&gt;Add&lt;/code&gt;, &lt;code&gt;Div&lt;/code&gt;, &lt;code&gt; Integer&lt;/code&gt;, &lt;code&gt;MatchProperty&lt;/code&gt;, &lt;code&gt;Max&lt;/code&gt;, &lt;code&gt;Min&lt;/code&gt;, &lt;code&gt;Mod&lt;/code&gt;, &lt;code&gt;Mul&lt;/code&gt;, &lt;code&gt;Neg&lt;/code&gt;, &lt;code&gt;Null&lt;/code&gt;, &lt;code&gt; Sub&lt;/code&gt;, &lt;code&gt;VariableRef&lt;/code&gt;, &lt;code&gt;ViewProperty&lt;/code&gt;, &lt;code&gt;Case&lt;/code&gt;; 
&lt;/li&gt;
&lt;li&gt;
conditions to deal with booleans: &lt;code&gt;And&lt;/code&gt;, &lt;code&gt;EQ&lt;/code&gt;, &lt;code&gt;GE&lt;/code&gt;, &lt;code&gt;GT&lt;/code&gt;, &lt;code&gt;IsMatch&lt;/code&gt;, &lt;code&gt;LE&lt;/code&gt;, &lt;code&gt;LT&lt;/code&gt;, &lt;code&gt; NE&lt;/code&gt;, &lt;code&gt;Not&lt;/code&gt;, &lt;code&gt;Or&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
At present there is no a specification of a report definitions. Probably, it&amp;#39;s
the most complex part to create such a spec for a user without deep knowledge. At
present, our idea is that one should use xml schema (we should polish generated schema)
for the report definition and schema aware editor to build report definitions. That&amp;#39;s
very robust approach working perfectly with &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2fct.ashx%3fid%3d4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b%26url%3dhttp%253a%252f%252fwww.nesterovsky-bros.com%252fdownload%252flanguages-xom.zip"&gt; languages
xom&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
C# sources can be found at: &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2fct.ashx%3fid%3d4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b%26url%3dhttp%253a%252f%252fwww.nesterovsky-bros.com%252fdownload%252freports%252fReportLayout.zip"&gt; ReportLayout.zip&lt;/a&gt; including
report definition classes and a sample report.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,4bd12ef0-e5cb-47a3-a7af-d60bc3fddd2b.aspx</comments>
      <category>Announce</category>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=997d3d31-cfc8-4555-99a9-0321a5e9bcf2</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,997d3d31-cfc8-4555-99a9-0321a5e9bcf2.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,997d3d31-cfc8-4555-99a9-0321a5e9bcf2.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=997d3d31-cfc8-4555-99a9-0321a5e9bcf2</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <img src="http://www.nesterovsky-bros.com/images/Ribbon_of_Saint_George.png" title="Memory of our grand parents" alt="Ribbon of Saint George" style="float: right" />
        <p>
We're facing a task of parsing reports produced from legacy applications and converting
them into a structured form, e.g. into xml. These xml files can be processed further
with up to date tools to produce good looking reports.
</p>
        <p>
Reports at hands are of very different structure and of size: from a couple of KB
to a several GB. The good part is that they mostly have a tabular form, so it's
easy to think of specific parsers in case of each report type.
</p>
        <p>
Our goal is to create an environment where a less qualified person(s) could create
and manage such parsers, and only rarely to engage someone who will handle less untrivial
cases.
</p>
        <p>
Our analysis has shown that it's possible to write such parser in almost any language:
xslt, C#, java.
</p>
        <p>
Our approach was to create an xml schema annotations that from one side define a data
structure, and from the other map report layout. Then we're able to create an
xslt that will generate either xslt, C#, or java parser according to the schema definitions.
Because of <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=997d3d31-cfc8-4555-99a9-0321a5e9bcf2&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip">languages
xom</a>, providing XML Object Model and serialization stylesheets for C# and java,
it does not really matter what we shall generate xslt or C#/java, as code will look
the same.
</p>
        <p>
The approach we're going to use to describe reports is not as powerfull as conventional
parsers. Its virtue, however, is simplicity of specification.
</p>
        <p>
Consider a report sample (a data to extract is in bold):
</p>
        <pre style="padding-left: 1em;">1 TITLE ...                    PAGE:            1
 BUSINESS DATE: <b>09/30/09</b> ...
RUN DATE: 02/23/10 CYCLE : ITD RUN: 001 ... RUN TIME: 09:22:39 CM BUS ... CO NBR FRM
FUNC ... ----- ----- ----- ----- <b>XXX</b><b>065</b><b>065</b><b>CLR</b> ... <b>YYY</b> ...
... 1 TITLE ... PAGE: 2 BUSINESS DATE: 09/30/09 ... RUN DATE: 02/23/10 CYCLE : ITD
RUN: 001 ... RUN TIME: 09:22:39 CM BUS ... CO NBR FRM FUNC ... ----- ----- ----- ----- <b>AAA</b><b>NNN</b><b>MMM</b><b>PPP</b> ... <b>BBB</b> ...
... * * * * * E N D O F R E P O R T * * * * *</pre>
        <p>
We're approaching to the report through a sequence of views (filters) of this
report. Each veiw localizes some report data either for the subsequent filterring
or for the extraction of final data.
</p>
        <p>
Looking into the example one can build following views of the report:
</p>
        <ol>
          <li>
View of data before the "E N D   O F   R E P O R T"
line.</li>
          <li>
View of remaining data without page headers and footers.</li>
          <li>
Views of table rows.</li>
          <li>
Views of cells.</li>
        </ol>
        <p>
A sequence of filters allows us to build a pipeline of transformations of original
text. This also allows us to generate a clean xslt, C# or java code to parse the data.
</p>
        <p>
At first, our favorite language for such parser was xslt. Unfortunatelly, we're
dealing with Saxon xslt implementation, which is not very strong in streaming processing.
Without a couple of extension functions to prevent caching, it tends to cache whole
input in the memory, which is not acceptable.
</p>
        <p>
At present we have decided to start from C# code, which is pure C# naturally. :-)
</p>
        <p>
Code still is in the development but at present we would like to share the xml schema
annotations describing report layout: <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=997d3d31-cfc8-4555-99a9-0321a5e9bcf2&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2freports%2freport-mapping.xsd"> report-mapping.xsd</a>,
and a sample of report description: <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=997d3d31-cfc8-4555-99a9-0321a5e9bcf2&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2freports%2ftest.xsd">test.xsd</a>.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=997d3d31-cfc8-4555-99a9-0321a5e9bcf2" />
      </body>
      <title>Parsing reports</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,997d3d31-cfc8-4555-99a9-0321a5e9bcf2.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/05/09/ParsingReports.aspx</link>
      <pubDate>Sun, 09 May 2010 05:18:57 GMT</pubDate>
      <description>&lt;img src="http://www.nesterovsky-bros.com/images/Ribbon_of_Saint_George.png" title="Memory of our grand parents" alt="Ribbon of Saint George" style="float: right" /&gt; 
&lt;p&gt;
We&amp;#39;re facing a task of parsing reports produced from legacy applications and converting
them into a structured form, e.g. into xml. These xml files can be processed further
with up to date tools to produce good looking reports.
&lt;/p&gt;
&lt;p&gt;
Reports at hands are of very different structure and of size: from a couple of KB
to a several GB. The good part is that they mostly have a tabular form, so it&amp;#39;s
easy to think of specific parsers in case of each report type.
&lt;/p&gt;
&lt;p&gt;
Our goal is to create an environment where a less qualified person(s) could create
and manage such parsers, and only rarely to engage someone who will handle less untrivial
cases.
&lt;/p&gt;
&lt;p&gt;
Our analysis has shown that it&amp;#39;s possible to write such parser in almost any language:
xslt, C#, java.
&lt;/p&gt;
&lt;p&gt;
Our approach was to create an xml schema annotations that from one side define a data
structure, and from the other map report layout. Then we&amp;#39;re able to create an
xslt that will generate either xslt, C#, or java parser according to the schema definitions.
Because of &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=997d3d31-cfc8-4555-99a9-0321a5e9bcf2&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip"&gt;languages
xom&lt;/a&gt;, providing XML Object Model and serialization stylesheets for C# and java,
it does not really matter what we shall generate xslt or C#/java, as code will look
the same.
&lt;/p&gt;
&lt;p&gt;
The approach we&amp;#39;re going to use to describe reports is not as powerfull as conventional
parsers. Its virtue, however, is simplicity of specification.
&lt;/p&gt;
&lt;p&gt;
Consider a report sample (a data to extract is in bold):
&lt;/p&gt;
&lt;pre style="padding-left: 1em;"&gt;1 TITLE ...                    PAGE:            1
 BUSINESS DATE: &lt;b&gt;09/30/09&lt;/b&gt; ...
RUN DATE: 02/23/10 CYCLE : ITD RUN: 001 ... RUN TIME: 09:22:39 CM BUS ... CO NBR FRM
FUNC ... ----- ----- ----- ----- &lt;b&gt;XXX&lt;/b&gt; &lt;b&gt;065&lt;/b&gt; &lt;b&gt;065&lt;/b&gt; &lt;b&gt;CLR&lt;/b&gt; ... &lt;b&gt;YYY&lt;/b&gt; ...
... 1 TITLE ... PAGE: 2 BUSINESS DATE: 09/30/09 ... RUN DATE: 02/23/10 CYCLE : ITD
RUN: 001 ... RUN TIME: 09:22:39 CM BUS ... CO NBR FRM FUNC ... ----- ----- ----- ----- &lt;b&gt;AAA&lt;/b&gt; &lt;b&gt;NNN&lt;/b&gt; &lt;b&gt;MMM&lt;/b&gt; &lt;b&gt;PPP&lt;/b&gt; ... &lt;b&gt;BBB&lt;/b&gt; ...
... * * * * * E N D O F R E P O R T * * * * *&lt;/pre&gt;
&lt;p&gt;
We&amp;#39;re approaching to the report through a sequence of views (filters) of this
report. Each veiw localizes some report data either for the subsequent filterring
or for the extraction of final data.
&lt;/p&gt;
&lt;p&gt;
Looking into the example one can build following views of the report:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
View of data before the &amp;quot;E N D&amp;nbsp;&amp;nbsp; O F&amp;nbsp;&amp;nbsp; R E P O R T&amp;quot;
line.&lt;/li&gt;
&lt;li&gt;
View of remaining data without page headers and footers.&lt;/li&gt;
&lt;li&gt;
Views of table rows.&lt;/li&gt;
&lt;li&gt;
Views of cells.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
A sequence of filters allows us to build a pipeline of transformations of original
text. This also allows us to generate a clean xslt, C# or java code to parse the data.
&lt;/p&gt;
&lt;p&gt;
At first, our favorite language for such parser was xslt. Unfortunatelly, we&amp;#39;re
dealing with Saxon xslt implementation, which is not very strong in streaming processing.
Without a couple of extension functions to prevent caching, it tends to cache whole
input in the memory, which is not acceptable.
&lt;/p&gt;
&lt;p&gt;
At present we have decided to start from C# code, which is pure C# naturally. :-)
&lt;/p&gt;
&lt;p&gt;
Code still is in the development but at present we would like to share the xml schema
annotations describing report layout: &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=997d3d31-cfc8-4555-99a9-0321a5e9bcf2&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2freports%2freport-mapping.xsd"&gt; report-mapping.xsd&lt;/a&gt;,
and a sample of report description: &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=997d3d31-cfc8-4555-99a9-0321a5e9bcf2&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2freports%2ftest.xsd"&gt;test.xsd&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=997d3d31-cfc8-4555-99a9-0321a5e9bcf2" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,997d3d31-cfc8-4555-99a9-0321a5e9bcf2.aspx</comments>
      <category>Announce</category>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=00dd8c3a-9063-4a09-b3fb-5dc55e98954c</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,00dd8c3a-9063-4a09-b3fb-5dc55e98954c.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,00dd8c3a-9063-4a09-b3fb-5dc55e98954c.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=00dd8c3a-9063-4a09-b3fb-5dc55e98954c</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A few little changes in streaming and in name normalization algorithms in jxom and
in csharpxom and the generation speed almost doubled (especially for big files).
</p>
        <p>
We suspect, however, that our xslt code is tuned for saxon engine. 
</p>
        <p>
It would be nice to know if anybody used languages XOM with other engines. Is anyone
using it at all (well, at least there are downloads)?
</p>
        <p>
Languages XOM (jxom, csharpxom, cobolxom, sqlxom) can be loaded from: <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=00dd8c3a-9063-4a09-b3fb-5dc55e98954c&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip"> languages-xom.zip</a></p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=00dd8c3a-9063-4a09-b3fb-5dc55e98954c" />
      </body>
      <title>Languages XOM update</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,00dd8c3a-9063-4a09-b3fb-5dc55e98954c.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/05/05/LanguagesXOMUpdate.aspx</link>
      <pubDate>Wed, 05 May 2010 06:48:10 GMT</pubDate>
      <description>&lt;p&gt;
A few little changes in streaming and in name normalization algorithms in jxom and
in csharpxom and the generation speed almost doubled (especially for big files).
&lt;/p&gt;
&lt;p&gt;
We suspect, however, that our xslt code is tuned for saxon engine. 
&lt;/p&gt;
&lt;p&gt;
It would be nice to know if anybody used languages XOM with other engines. Is anyone
using it at all (well, at least there are downloads)?
&lt;/p&gt;
&lt;p&gt;
Languages XOM (jxom, csharpxom, cobolxom, sqlxom) can be loaded from: &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=00dd8c3a-9063-4a09-b3fb-5dc55e98954c&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip"&gt; languages-xom.zip&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=00dd8c3a-9063-4a09-b3fb-5dc55e98954c" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,00dd8c3a-9063-4a09-b3fb-5dc55e98954c.aspx</comments>
      <category>Announce</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=d9305737-1141-43d8-9c4b-328e576a7e62</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,d9305737-1141-43d8-9c4b-328e576a7e62.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,d9305737-1141-43d8-9c4b-328e576a7e62.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=d9305737-1141-43d8-9c4b-328e576a7e62</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
At times a simple task in xslt looks like a puzzle. Today we have this one.
</p>
        <p>
For a string and a regular expression find a position and a length of the matched
substring.
</p>
        <p>
The problem looks so simple that you do not immediaty realize that you are going to
spend ten minutes trying to solve it in the best way.
</p>
        <p>
Try it yourself before proceeding:<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /></p>
        <p style="padding-left: 1em">
          <code>&lt;xsl:variable name="match" as="xs:integer*"&gt;<br />
  &lt;xsl:analyze-string select="$line" regex="my-reg-ex"&gt;<br />
    &lt;xsl:matching-substring&gt;<br />
      &lt;xsl:sequence select="1, string-length(.)"/&gt;<br />
    &lt;/xsl:matching-substring&gt;<br />
    &lt;xsl:non-matching-substring&gt;<br />
      &lt;xsl:sequence select="0, string-length(.)"/&gt;<br />
    &lt;/xsl:non-matching-substring&gt;<br />
  &lt;/xsl:analyze-string&gt;<br />
&lt;/xsl:variable&gt;<br /><br />
&lt;xsl:choose&gt;<br />
  &lt;xsl:when test="$match[1]"&gt;<br />
    &lt;xsl:sequence select="1, $match[2]"/&gt;<br />
  &lt;/xsl:when&gt;<br />
  &lt;xsl:when test="$match[3]"&gt;<br />
    &lt;xsl:sequence select="$match[2], $match[4]"/&gt;<br />
  &lt;/xsl:when&gt;<br />
&lt;/xsl:choose&gt;</code>
        </p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=d9305737-1141-43d8-9c4b-328e576a7e62" />
      </body>
      <title>Xslt match puzzle</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,d9305737-1141-43d8-9c4b-328e576a7e62.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/05/02/XsltMatchPuzzle.aspx</link>
      <pubDate>Sun, 02 May 2010 15:35:02 GMT</pubDate>
      <description>&lt;p&gt;
At times a simple task in xslt looks like a puzzle. Today we have this one.
&lt;/p&gt;
&lt;p&gt;
For a string and a regular expression find a position and a length of the matched
substring.
&lt;/p&gt;
&lt;p&gt;
The problem looks so simple that you do not immediaty realize that you are going to
spend ten minutes trying to solve it in the best way.
&lt;/p&gt;
&lt;p&gt;
Try it yourself before proceeding:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&amp;lt;xsl:variable name="match" as="xs:integer*"&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:analyze-string select="$line" regex="my-reg-ex"&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:matching-substring&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select="1, string-length(.)"/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/xsl:matching-substring&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:non-matching-substring&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select="0, string-length(.)"/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/xsl:non-matching-substring&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/xsl:analyze-string&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:variable&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;xsl:choose&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:when test="$match[1]"&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select="1, $match[2]"/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/xsl:when&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:when test="$match[3]"&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select="$match[2], $match[4]"/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/xsl:when&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:choose&amp;gt;&lt;/code&gt; 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=d9305737-1141-43d8-9c4b-328e576a7e62" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,d9305737-1141-43d8-9c4b-328e576a7e62.aspx</comments>
      <category>Tips and tricks</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=a4bfe4ce-ea72-4ad7-bffc-36c02ade1b44</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,a4bfe4ce-ea72-4ad7-bffc-36c02ade1b44.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,a4bfe4ce-ea72-4ad7-bffc-36c02ade1b44.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=a4bfe4ce-ea72-4ad7-bffc-36c02ade1b44</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
To see that the problem with <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a4bfe4ce-ea72-4ad7-bffc-36c02ade1b44&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2010%2f04%2f09%2fGeneratorFunctionsInXslt.aspx">Generator
functions in xslt</a> is a bit more complicated compare two functions.
</p>
        <p>
The first one is quoted from the earlier post:
</p>
        <p>
          <code>  &lt;xsl:function name="t:generate" as="xs:integer*"&gt;<br />
    &lt;xsl:param name="value" as="xs:integer"/&gt;<br /><br />
    &lt;xsl:sequence select="$value"/&gt;<br />
    &lt;xsl:sequence select="t:generate($value * 2)"/&gt;<br />
  &lt;/xsl:function&gt;<br /></code>
        </p>
        <p>
It does not work in Saxon: crashes with out of memory.
</p>
        <p>
The second one is slightly modified version of the same function:
</p>
        <p>
          <code>  &lt;xsl:function name="t:generate" as="xs:integer*"&gt;<br />
    &lt;xsl:param name="value" as="xs:integer"/&gt;<br /><br />
    &lt;xsl:sequence select="$value <span style="color: red; font-weight: bold;">+
0</span>"/&gt;<br />
    &lt;xsl:sequence select="t:generate($value * 2)"/&gt;<br />
  &lt;/xsl:function&gt;<br /></code>
        </p>
        <p>
It's working without problems. In first case Saxon decides to cache all function's
output, in the second case it decides to evaluate data lazily on demand.
</p>
        <p>
It seems that optimization algorithms implemented in Saxon are so plentiful and complex
that at times they fool one another. :-)
</p>
        <p>
See also: <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a4bfe4ce-ea72-4ad7-bffc-36c02ade1b44&amp;url=http%3a%2f%2fsourceforge.net%2fprojects%2fsaxon%2fforums%2fforum%2f94026%2ftopic%2f3690966"> Generator
functions</a></p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=a4bfe4ce-ea72-4ad7-bffc-36c02ade1b44" />
      </body>
      <title>Generator functions in xslt in Saxon</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,a4bfe4ce-ea72-4ad7-bffc-36c02ade1b44.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/05/01/GeneratorFunctionsInXsltInSaxon.aspx</link>
      <pubDate>Sat, 01 May 2010 07:18:24 GMT</pubDate>
      <description>   &lt;p&gt;
To see that the problem with &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a4bfe4ce-ea72-4ad7-bffc-36c02ade1b44&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2010%2f04%2f09%2fGeneratorFunctionsInXslt.aspx"&gt;Generator
functions in xslt&lt;/a&gt; is a bit more complicated compare two functions.
&lt;/p&gt;
&lt;p&gt;
The first one is quoted from the earlier post:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt;&amp;nbsp; &amp;lt;xsl:function name=&amp;quot;t:generate&amp;quot; as=&amp;quot;xs:integer*&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:param name=&amp;quot;value&amp;quot; as=&amp;quot;xs:integer&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select=&amp;quot;$value&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select=&amp;quot;t:generate($value * 2)&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/xsl:function&amp;gt;&lt;br /&gt;
&lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
It does not work in Saxon: crashes with out of memory.
&lt;/p&gt;
&lt;p&gt;
The second one is slightly modified version of the same function:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt;&amp;nbsp; &amp;lt;xsl:function name=&amp;quot;t:generate&amp;quot; as=&amp;quot;xs:integer*&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:param name=&amp;quot;value&amp;quot; as=&amp;quot;xs:integer&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select=&amp;quot;$value &lt;span style="color: red; font-weight: bold;"&gt;+
0&lt;/span&gt;&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select=&amp;quot;t:generate($value * 2)&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/xsl:function&amp;gt;&lt;br /&gt;
&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
It&amp;#39;s working without problems. In first case Saxon decides to cache all function&amp;#39;s
output, in the second case it decides to evaluate data lazily on demand.
&lt;/p&gt;
&lt;p&gt;
It seems that optimization algorithms implemented in Saxon are so plentiful and complex
that at times they fool one another. :-&amp;#x29;
&lt;/p&gt;
&lt;p&gt;
See also: &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a4bfe4ce-ea72-4ad7-bffc-36c02ade1b44&amp;amp;url=http%3a%2f%2fsourceforge.net%2fprojects%2fsaxon%2fforums%2fforum%2f94026%2ftopic%2f3690966"&gt; Generator
functions&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=a4bfe4ce-ea72-4ad7-bffc-36c02ade1b44" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,a4bfe4ce-ea72-4ad7-bffc-36c02ade1b44.aspx</comments>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=17f3125a-f778-4ff5-ac10-9969c426eaa2</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,17f3125a-f778-4ff5-ac10-9969c426eaa2.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,17f3125a-f778-4ff5-ac10-9969c426eaa2.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=17f3125a-f778-4ff5-ac10-9969c426eaa2</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
There are some complications with streamed tree that we have implemented in saxon.
They are due to the fact that only a view of input data is available at any time.
Whenever you access some element that's is not available you're getting an
exception.
</p>
        <p>
Consider an example. We have a log created with java logging. It looks like this:
</p>
        <p style="padding-left: 1em">
          <code>&lt;log&gt;<br />
  &lt;record&gt;<br />
    &lt;date&gt;...&lt;/date&gt;<br />
    &lt;millis&gt;...&lt;/millis&gt;<br />
    &lt;sequence&gt;...&lt;/sequence&gt;<br />
    &lt;logger&gt;...&lt;/logger&gt;<br />
    &lt;level&gt;INFO&lt;/level&gt;<br />
    &lt;class&gt;...&lt;/class&gt;<br />
    &lt;method&gt;...&lt;/method&gt;<br />
    &lt;thread&gt;...&lt;/thread&gt;<br />
    &lt;message&gt;...&lt;/message&gt;<br />
  &lt;/record&gt;<br />
  &lt;record&gt;<br />
    ...<br />
  &lt;/record&gt;<br />
  ...</code>
        </p>
        <p>
We would like to write an xslt that returns a page of log as html:
</p>
        <p style="padding-left: 1em">
          <code>&lt;xsl:stylesheet version="2.0"<br />
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"<br />
  xmlns:xs="http://www.w3.org/2001/XMLSchema"<br />
  xmlns:t="http://www.nesterovsky-bros.com/xslt/this"<br />
  xmlns="http://www.w3.org/1999/xhtml"<br />
  exclude-result-prefixes="xs t"&gt;<br /><br />
  &lt;xsl:param name="start-page" as="xs:integer" select="1"/&gt;<br />
  &lt;xsl:param name="page-size" as="xs:integer" select="50"/&gt;<br /><br />
  &lt;xsl:output method="xhtml" byte-order-mark="yes" indent="yes"/&gt;<br /><br />
  &lt;!-- Entry point. --&gt;<br />
  &lt;xsl:template match="/log"&gt;<br />
    &lt;xsl:variable name="start" as="xs:integer"<br />
      select="($start-page - 1) * $page-size + 1"/&gt;<br />
    &lt;xsl:variable name="records" as="element()*"<br />
      select="subsequence(record, $start, $page-size)"/&gt;<br /><br />
    &lt;html&gt;<br />
      &lt;head&gt;<br />
        &lt;title&gt;<br />
          &lt;xsl:text&gt;A log file.
Page: &lt;/xsl:text&gt;<br />
          &lt;xsl:value-of select="$start-page"/&gt;<br />
        &lt;/title&gt;<br />
      &lt;/head&gt;<br />
      &lt;body&gt;<br />
        &lt;table border="1"&gt;<br />
          &lt;thead&gt;<br />
            &lt;tr&gt;<br />
              &lt;th&gt;Level&lt;/th&gt;<br />
              &lt;th&gt;Message&lt;/th&gt;<br />
            &lt;/tr&gt;<br />
          &lt;/thead&gt;<br />
          &lt;tbody&gt;<br />
            &lt;xsl:apply-templates
mode="t:record" select="$records"/&gt;<br />
          &lt;/tbody&gt;<br />
        &lt;/table&gt;<br />
      &lt;/body&gt;<br />
    &lt;/html&gt;<br />
  &lt;/xsl:template&gt;<br /><br />
  &lt;xsl:template mode="t:record" match="record"&gt;<br />
    &lt;!-- Make a copy of record to avoid streaming access problems.
--&gt;<br />
    &lt;xsl:variable name="log"&gt;<br />
      &lt;xsl:copy-of select="."/&gt;<br />
    &lt;/xsl:variable&gt;<br /><br />
    &lt;xsl:variable name="level" as="xs:string"<br />
      select="$log/record/level"/&gt;<br />
    &lt;xsl:variable name="message" as="xs:string"<br />
      select="$log/record/message"/&gt;<br /><br />
    &lt;tr&gt;<br />
      &lt;td&gt;<br />
        &lt;xsl:value-of select="$level"/&gt;<br />
      &lt;/td&gt;<br />
      &lt;td&gt;<br />
        &lt;xsl:value-of select="$message"/&gt;<br />
      &lt;/td&gt;<br />
    &lt;/tr&gt;<br />
  &lt;/xsl:template&gt;<br /><br />
&lt;/xsl:stylesheet&gt;</code>
        </p>
        <p>
This code does not work. Guess why? Yes, it's <code>subsequence()</code>, which
is too greedy. It always wants to know what's the next node, so it naturally skips
a content of the current node. Algorithmically, such saxon code could be rewritten,
and could possibly work better also in modes other than streaming.
</p>
        <p>
A viable workaround, which does not use subsequence, looks rather untrivial:
</p>
        <p style="padding-left: 1em">
          <code> &lt;!-- Entry point. --&gt;<br />
&lt;xsl:template match="/log"&gt;<br />
  &lt;xsl:variable name="start" as="xs:integer"<br />
    select="($start-page - 1) * $page-size + 1"/&gt;<br />
  &lt;xsl:variable name="end" as="xs:integer"<br />
    select="$start + $page-size"/&gt;<br /><br />
  &lt;html&gt;<br />
    &lt;head&gt;<br />
      &lt;title&gt;<br />
        &lt;xsl:text&gt;A log file. Page: &lt;/xsl:text&gt;<br />
        &lt;xsl:value-of select="$start-page"/&gt;<br />
      &lt;/title&gt;<br />
    &lt;/head&gt;<br />
    &lt;body&gt;<br />
      &lt;table border="1"&gt;<br />
        &lt;thead&gt;<br />
          &lt;tr&gt;<br />
            &lt;th&gt;Level&lt;/th&gt;<br />
            &lt;th&gt;Message&lt;/th&gt;<br />
          &lt;/tr&gt;<br />
        &lt;/thead&gt;<br />
        &lt;tbody&gt;<br />
          &lt;xsl:sequence select="<br />
            t:generate-records(record,
$start, $end, ())"/&gt;<br />
        &lt;/tbody&gt;<br />
      &lt;/table&gt;<br />
    &lt;/body&gt;<br />
  &lt;/html&gt;<br />
&lt;/xsl:template&gt;<br /><br />
&lt;xsl:function name="t:generate-records" as="element()*"&gt;<br />
  &lt;xsl:param name="records" as="element()*"/&gt;<br />
  &lt;xsl:param name="start" as="xs:integer"/&gt;<br />
  &lt;xsl:param name="end" as="xs:integer?"/&gt;<br />
  &lt;xsl:param name="result" as="element()*"/&gt;<br /><br />
  &lt;xsl:variable name="record" as="element()?" select="$records[$start]"/&gt;<br /><br />
  &lt;xsl:choose&gt;<br />
    &lt;xsl:when test="(exists($end) and ($start &gt; $end)) or empty($record)"&gt;<br />
      &lt;xsl:sequence select="$result"/&gt;<br />
    &lt;/xsl:when&gt;<br />
    &lt;xsl:otherwise&gt;<br />
      &lt;!-- Make a copy of record to avoid streaming access
problems. --&gt;<br />
      &lt;xsl:variable name="log"&gt;<br />
        &lt;xsl:copy-of select="$record"/&gt;<br />
      &lt;/xsl:variable&gt;<br /><br />
      &lt;xsl:variable name="level" as="xs:string"<br />
        select="$log/record/level"/&gt;<br />
      &lt;xsl:variable name="message" as="xs:string"<br />
        select="$log/record/message"/&gt;<br /><br />
      &lt;xsl:variable name="next-result" as="element()*"&gt;<br />
        &lt;tr&gt;<br />
          &lt;td&gt;<br />
            &lt;xsl:value-of
select="$level"/&gt;<br />
          &lt;/td&gt;<br />
          &lt;td&gt;<br />
            &lt;xsl:value-of
select="$message"/&gt;<br />
          &lt;/td&gt;<br />
        &lt;/tr&gt;<br />
      &lt;/xsl:variable&gt;<br /><br />
      &lt;xsl:sequence select="<br />
        t:generate-records<br />
        (<br />
          $records,<br />
          $start + 1,<br />
          $end,<br />
          ($result, $next-result)<br />
        )"/&gt;<br />
    &lt;/xsl:otherwise&gt;<br />
  &lt;/xsl:choose&gt;<br />
&lt;/xsl:function&gt;</code>
        </p>
        <p>
Here we observed the greediness of saxon, which too early tried to consume more input
than it's required. In the other cases we have seen that it may defer actual data
access to the point when there is no data anymore.
</p>
        <p>
So, without tuning internal saxon logic it's possible but not easy to write stylesheets
that exploit streaming features.
</p>
        <p>
P.S. Updated sources are at <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=17f3125a-f778-4ff5-ac10-9969c426eaa2&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fsaxon%2fstreamedtree.zip"> streamedtree.zip</a></p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=17f3125a-f778-4ff5-ac10-9969c426eaa2" />
      </body>
      <title>Complications with streamed tree</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,17f3125a-f778-4ff5-ac10-9969c426eaa2.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/04/23/ComplicationsWithStreamedTree.aspx</link>
      <pubDate>Fri, 23 Apr 2010 10:12:38 GMT</pubDate>
      <description>&lt;p&gt;
There are some complications with streamed tree that we have implemented in saxon.
They are due to the fact that only a view of input data is available at any time.
Whenever you access some element that&amp;#39;s is not available you&amp;#39;re getting an
exception.
&lt;/p&gt;
&lt;p&gt;
Consider an example. We have a log created with java logging. It looks like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&amp;lt;log&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;record&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;date&amp;gt;...&amp;lt;/date&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;millis&amp;gt;...&amp;lt;/millis&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;sequence&amp;gt;...&amp;lt;/sequence&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;logger&amp;gt;...&amp;lt;/logger&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;level&amp;gt;INFO&amp;lt;/level&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;class&amp;gt;...&amp;lt;/class&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;method&amp;gt;...&amp;lt;/method&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;thread&amp;gt;...&amp;lt;/thread&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;message&amp;gt;...&amp;lt;/message&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/record&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;record&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;lt;/record&amp;gt;&lt;br /&gt;
&amp;nbsp; ...&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
We would like to write an xslt that returns a page of log as html:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&amp;lt;xsl:stylesheet version="2.0"&lt;br /&gt;
&amp;nbsp; xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&lt;br /&gt;
&amp;nbsp; xmlns:xs="http://www.w3.org/2001/XMLSchema"&lt;br /&gt;
&amp;nbsp; xmlns:t="http://www.nesterovsky-bros.com/xslt/this"&lt;br /&gt;
&amp;nbsp; xmlns="http://www.w3.org/1999/xhtml"&lt;br /&gt;
&amp;nbsp; exclude-result-prefixes="xs t"&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:param name="start-page" as="xs:integer" select="1"/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:param name="page-size" as="xs:integer" select="50"/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:output method="xhtml" byte-order-mark="yes" indent="yes"/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;!-- Entry point. --&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:template match="/log"&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:variable name="start" as="xs:integer"&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select="($start-page - 1) * $page-size + 1"/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:variable name="records" as="element()*"&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select="subsequence(record, $start, $page-size)"/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;html&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;head&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;title&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:text&amp;gt;A log file.
Page: &amp;lt;/xsl:text&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:value-of select="$start-page"/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;body&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;table border="1"&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;thead&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;th&amp;gt;Level&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;th&amp;gt;Message&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/thead&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tbody&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:apply-templates
mode="t:record" select="$records"/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/tbody&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:template mode="t:record" match="record"&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;!-- Make a copy of record to avoid streaming access problems.
--&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:variable name="log"&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:copy-of select="."/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/xsl:variable&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:variable name="level" as="xs:string"&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select="$log/record/level"/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:variable name="message" as="xs:string"&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select="$log/record/message"/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;td&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:value-of select="$level"/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;td&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:value-of select="$message"/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/xsl:stylesheet&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
This code does not work. Guess why? Yes, it&amp;#39;s &lt;code&gt;subsequence()&lt;/code&gt;, which
is too greedy. It always wants to know what&amp;#39;s the next node, so it naturally skips
a content of the current node. Algorithmically, such saxon code could be rewritten,
and could possibly work better also in modes other than streaming.
&lt;/p&gt;
&lt;p&gt;
A viable workaround, which does not use subsequence, looks rather untrivial:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; &amp;lt;!-- Entry point. --&amp;gt;&lt;br /&gt;
&amp;lt;xsl:template match="/log"&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:variable name="start" as="xs:integer"&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; select="($start-page - 1) * $page-size + 1"/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:variable name="end" as="xs:integer"&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; select="$start + $page-size"/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;html&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;head&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;title&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:text&amp;gt;A log file. Page: &amp;lt;/xsl:text&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:value-of select="$start-page"/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;body&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;table border="1"&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;thead&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;th&amp;gt;Level&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;th&amp;gt;Message&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/thead&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tbody&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select="&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t:generate-records(record,
$start, $end, ())"/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/tbody&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;xsl:function name="t:generate-records" as="element()*"&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:param name="records" as="element()*"/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:param name="start" as="xs:integer"/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:param name="end" as="xs:integer?"/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:param name="result" as="element()*"/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:variable name="record" as="element()?" select="$records[$start]"/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:choose&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:when test="(exists($end) and ($start &amp;gt; $end)) or empty($record)"&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select="$result"/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/xsl:when&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:otherwise&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;!-- Make a copy of record to avoid streaming access
problems. --&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:variable name="log"&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:copy-of select="$record"/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/xsl:variable&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:variable name="level" as="xs:string"&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select="$log/record/level"/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:variable name="message" as="xs:string"&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select="$log/record/message"/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:variable name="next-result" as="element()*"&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;td&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:value-of
select="$level"/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;td&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:value-of
select="$message"/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/xsl:variable&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select="&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t:generate-records&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $records,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $start + 1,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $end,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ($result, $next-result)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; )"/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/xsl:otherwise&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/xsl:choose&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:function&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Here we observed the greediness of saxon, which too early tried to consume more input
than it&amp;#39;s required. In the other cases we have seen that it may defer actual data
access to the point when there is no data anymore.
&lt;/p&gt;
&lt;p&gt;
So, without tuning internal saxon logic it&amp;#39;s possible but not easy to write stylesheets
that exploit streaming features.
&lt;/p&gt;
&lt;p&gt;
P.S. Updated sources are at &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=17f3125a-f778-4ff5-ac10-9969c426eaa2&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fsaxon%2fstreamedtree.zip"&gt; streamedtree.zip&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=17f3125a-f778-4ff5-ac10-9969c426eaa2" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,17f3125a-f778-4ff5-ac10-9969c426eaa2.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=ccb28496-2a41-45b4-92f5-195861912562</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,ccb28496-2a41-45b4-92f5-195861912562.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,ccb28496-2a41-45b4-92f5-195861912562.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=ccb28496-2a41-45b4-92f5-195861912562</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
When time has come to process big xml log files we've decided to implement streamable
tree in saxon the very same way it was implemented in .net eight years ago (see <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=ccb28496-2a41-45b4-92f5-195861912562&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2010%2f04%2f04%2fHowWouldWeApproachToStreamingFacilityInXslt.aspx"> How
would we approach to streaming facility in xslt</a>).
</p>
        <p>
It's interesting enough that the implementation is similar to one of <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=ccb28496-2a41-45b4-92f5-195861912562&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2010%2f04%2f08%2fComposableTreeModelInSaxon.aspx"> composable
tree</a>. There a node never stores a reference to a parent, while in the streamed
tree no references to children are stored. This way only a limited subview of tree
is available at any time. Implementation does not support preceding and preceding-sibling
axes. Also, one cannot navigate to a node that is out of scope.
</p>
        <p>
Implementation is external (there are no changes to saxon itself). To use it one needs
to create an instance of <code>DocumentInfo</code>, which pulls data from <code><a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=ccb28496-2a41-45b4-92f5-195861912562&amp;url=http%3a%2f%2fjava.sun.com%2fjavase%2f6%2fdocs%2fapi%2fjavax%2fxml%2fstream%2fXMLStreamReader.html">XMLStreamReader</a></code>,
and to pass it as an input to a transformation:
</p>
        <p style="padding-left: 1em">
          <code>Controller controller = (Controller)transformer; 
<br />
XMLInputFactory factory = XMLInputFactory.newInstance();<br />
StreamSource inputSource = new StreamSource(new File(input)); 
<br />
XMLStreamReader reader = factory.createXMLStreamReader(inputSource);<br />
StaxBridge bridge = new StaxBridge(); 
<br /><br />
bridge.setPipelineConfiguration(<br />
  controller.makePipelineConfiguration());<br />
bridge.setXMLStreamReader(reader); 
<br />
inputSource = new DocumentImpl(bridge);<br /><br />
transformer.transform(inputSource, new StreamResult(output));</code>
        </p>
        <p>
This helped us to format an xml log file of arbitrary size. An xslt like this can
do the work:
</p>
        <p>
          <code> &lt;xsl:stylesheet version="2.0"<br />
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"<br />
  xmlns:xs="http://www.w3.org/2001/XMLSchema"<br />
  xmlns="http://www.w3.org/1999/xhtml"<br />
  exclude-result-prefixes="xs"&gt;<br /><br />
  &lt;xsl:template match="/log"&gt;<br />
    &lt;html&gt;<br />
      &lt;head&gt;<br />
        &lt;title&gt;Log&lt;/title&gt;<br />
      &lt;/head&gt;<br />
      &lt;body&gt;<br />
        &lt;xsl:apply-templates/&gt; 
<br />
      &lt;/body&gt;<br />
    &lt;/html&gt;<br />
  &lt;/xsl:template&gt;<br /><br />
  &lt;xsl:template match="message"&gt;<br />
   ... 
<br />
  &lt;/xsl:template&gt;<br /><br />
  &lt;xsl:template match="message[@error]"&gt;<br />
    ... 
<br />
  &lt;/xsl:template&gt; 
<br /><br />
  ... 
<br /><br />
&lt;/xsl:stylesheet&gt;</code>
        </p>
        <p>
Implementation can be found at: <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=ccb28496-2a41-45b4-92f5-195861912562&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fsaxon%2fstreamedtree.zip"> streamedtree.zip</a></p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=ccb28496-2a41-45b4-92f5-195861912562" />
      </body>
      <title>Streamed tree</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,ccb28496-2a41-45b4-92f5-195861912562.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/04/21/StreamedTree.aspx</link>
      <pubDate>Wed, 21 Apr 2010 07:10:34 GMT</pubDate>
      <description>&lt;p&gt;
When time has come to process big xml log files we&amp;#39;ve decided to implement streamable
tree in saxon the very same way it was implemented in .net eight years ago (see &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=ccb28496-2a41-45b4-92f5-195861912562&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2010%2f04%2f04%2fHowWouldWeApproachToStreamingFacilityInXslt.aspx"&gt; How
would we approach to streaming facility in xslt&lt;/a&gt;).
&lt;/p&gt;
&lt;p&gt;
It&amp;#39;s interesting enough that the implementation is similar to one of &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=ccb28496-2a41-45b4-92f5-195861912562&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2010%2f04%2f08%2fComposableTreeModelInSaxon.aspx"&gt; composable
tree&lt;/a&gt;. There a node never stores a reference to a parent, while in the streamed
tree no references to children are stored. This way only a limited subview of tree
is available at any time. Implementation does not support preceding and preceding-sibling
axes. Also, one cannot navigate to a node that is out of scope.
&lt;/p&gt;
&lt;p&gt;
Implementation is external (there are no changes to saxon itself). To use it one needs
to create an instance of &lt;code&gt;DocumentInfo&lt;/code&gt;, which pulls data from &lt;code&gt; &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=ccb28496-2a41-45b4-92f5-195861912562&amp;amp;url=http%3a%2f%2fjava.sun.com%2fjavase%2f6%2fdocs%2fapi%2fjavax%2fxml%2fstream%2fXMLStreamReader.html"&gt;XMLStreamReader&lt;/a&gt;&lt;/code&gt;,
and to pass it as an input to a transformation:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;Controller controller = (Controller)transformer; 
&lt;br /&gt;
XMLInputFactory factory = XMLInputFactory.newInstance();&lt;br /&gt;
StreamSource inputSource = new StreamSource(new File(input)); 
&lt;br /&gt;
XMLStreamReader reader = factory.createXMLStreamReader(inputSource);&lt;br /&gt;
StaxBridge bridge = new StaxBridge(); 
&lt;br /&gt;
&lt;br /&gt;
bridge.setPipelineConfiguration(&lt;br /&gt;
&amp;nbsp; controller.makePipelineConfiguration());&lt;br /&gt;
bridge.setXMLStreamReader(reader); 
&lt;br /&gt;
inputSource = new DocumentImpl(bridge);&lt;br /&gt;
&lt;br /&gt;
transformer.transform(inputSource, new StreamResult(output));&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
This helped us to format an xml log file of arbitrary size. An xslt like this can
do the work:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt; &amp;lt;xsl:stylesheet version=&amp;quot;2.0&amp;quot;&lt;br /&gt;
&amp;nbsp; xmlns:xsl=&amp;quot;http://www.w3.org/1999/XSL/Transform&amp;quot;&lt;br /&gt;
&amp;nbsp; xmlns:xs=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&lt;br /&gt;
&amp;nbsp; xmlns=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&lt;br /&gt;
&amp;nbsp; exclude-result-prefixes=&amp;quot;xs&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:template match=&amp;quot;/log&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;html&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;head&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;title&amp;gt;Log&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;body&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:apply-templates/&amp;gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:template match=&amp;quot;message&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; ... 
&lt;br /&gt;
&amp;nbsp; &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:template match=&amp;quot;message[@error]&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ... 
&lt;br /&gt;
&amp;nbsp; &amp;lt;/xsl:template&amp;gt; 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; ... 
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/xsl:stylesheet&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Implementation can be found at: &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=ccb28496-2a41-45b4-92f5-195861912562&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fsaxon%2fstreamedtree.zip"&gt; streamedtree.zip&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=ccb28496-2a41-45b4-92f5-195861912562" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,ccb28496-2a41-45b4-92f5-195861912562.aspx</comments>
      <category>Announce</category>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=a8bea9ba-223a-4656-9494-430bbf28b345</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,a8bea9ba-223a-4656-9494-430bbf28b345.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,a8bea9ba-223a-4656-9494-430bbf28b345.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=a8bea9ba-223a-4656-9494-430bbf28b345</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
jxom else if (google search)
</p>
        <p>
Google helps with many things but with retrospective support.
</p>
        <p>
Probably guy's trying to build a nested if then else jxom elements.
</p>
        <p>
We expected this and have defined a function <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a8bea9ba-223a-4656-9494-430bbf28b345&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip">t:generate-if-statement()
in java-optimizer.xslt</a>.
</p>
        <p>
Its signature:
</p>
        <p style="padding-left: 1em">
          <code> &lt;!--<br />
  Generates if/then/else if ... statements.<br />
    $closure - a series of conditions and blocks.<br />
    $index - current index.<br />
    $result - collected result. 
<br />
    Returns if/then/else if ... statements.<br />
--&gt;<br />
&lt;xsl:function name="t:generate-if-statement" as="element()"&gt;<br />
  &lt;xsl:param name="closure" as="element()*"/&gt;<br />
  &lt;xsl:param name="index" as="xs:integer"/&gt;<br />
  &lt;xsl:param name="result" as="element()?"/&gt; </code>
        </p>
        <p style="padding-left: 1em">
Usage is like this:
</p>
        <p style="padding-left: 1em">
          <code> &lt;!-- Generate a sequence of pairs: (condition, scope). --&gt;<br />
&lt;xsl:variable name="branches" as="element()+"&gt;<br />
  &lt;xsl:for-each select="..."&gt;<br />
    &lt;!-- Generate condition. --&gt;<br />
    &lt;scope&gt;<br />
        &lt;!-- Generate statemetns.  --&gt;<br />
    &lt;/scope&gt;<br />
  &lt;/xsl:for-each&gt;<br />
&lt;/xsl:variable&gt;<br /><br />
&lt;xsl:variable name="else" as="element()?"&gt;<br />
  &lt;!-- Generate final else, if any. --&gt;<br />
&lt;/xsl:variable&gt;<br /><br />
&lt;!-- This generates if statement. --&gt;<br />
&lt;xsl:sequence 
<br />
  select="t:generate-if-statement($branches, count($branches) - 1, $else)"/&gt;</code>
        </p>
        <p>
P.S. By the way, we like that someone is looking into <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a8bea9ba-223a-4656-9494-430bbf28b345&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip">jxom</a>.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=a8bea9ba-223a-4656-9494-430bbf28b345" />
      </body>
      <title>jxom else if (google search)</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,a8bea9ba-223a-4656-9494-430bbf28b345.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/04/15/jxomElseIfGoogleSearch.aspx</link>
      <pubDate>Thu, 15 Apr 2010 06:59:01 GMT</pubDate>
      <description>&lt;p&gt;
jxom else if (google search)
&lt;/p&gt;
&lt;p&gt;
Google helps with many things but with retrospective support.
&lt;/p&gt;
&lt;p&gt;
Probably guy&amp;#39;s trying to build a nested if then else jxom elements.
&lt;/p&gt;
&lt;p&gt;
We expected this and have defined a function &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a8bea9ba-223a-4656-9494-430bbf28b345&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip"&gt;t:generate-if-statement()
in java-optimizer.xslt&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Its signature:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; &amp;lt;!--&lt;br /&gt;
&amp;nbsp; Generates if/then/else if ... statements.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; $closure - a series of conditions and blocks.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; $index - current index.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; $result - collected result. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Returns if/then/else if ... statements.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;xsl:function name="t:generate-if-statement" as="element()"&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:param name="closure" as="element()*"/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:param name="index" as="xs:integer"/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:param name="result" as="element()?"/&amp;gt; &lt;/code&gt; 
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
Usage is like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; &amp;lt;!-- Generate a sequence of pairs: (condition, scope). --&amp;gt;&lt;br /&gt;
&amp;lt;xsl:variable name=&amp;quot;branches&amp;quot; as=&amp;quot;element()+&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:for-each select=&amp;quot;...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;!-- Generate condition. --&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;scope&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;!-- Generate statemetns.&amp;nbsp; --&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/scope&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/xsl:for-each&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:variable&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;xsl:variable name=&amp;quot;else&amp;quot; as=&amp;quot;element()?&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;!-- Generate final else, if any. --&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:variable&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- This generates if statement. --&amp;gt;&lt;br /&gt;
&amp;lt;xsl:sequence 
&lt;br /&gt;
&amp;nbsp; select=&amp;quot;t:generate-if-statement($branches, count($branches) - 1, $else)&amp;quot;/&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
P.S. By the way, we like that someone is looking into &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=a8bea9ba-223a-4656-9494-430bbf28b345&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip"&gt;jxom&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=a8bea9ba-223a-4656-9494-430bbf28b345" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,a8bea9ba-223a-4656-9494-430bbf28b345.aspx</comments>
      <category>Tips and tricks</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=bc7a610a-31d5-40ac-aa6e-38e50c6ce932</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,bc7a610a-31d5-40ac-aa6e-38e50c6ce932.aspx</pingback:target>
      <dc:creator>Arthur Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,bc7a610a-31d5-40ac-aa6e-38e50c6ce932.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=bc7a610a-31d5-40ac-aa6e-38e50c6ce932</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
By the generator we assume a function that produces an infinitive output sequence
for a particular input.
</p>
        <p>
That's a rather theoretical question, as xslt does not allow infinitive sequence,
but look at the example:
</p>
        <p class="style1" style="PADDING-LEFT: 1em">
          <code>&lt;xsl:stylesheet version="2.0"<br />
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"<br />
  xmlns:xs="http://www.w3.org/2001/XMLSchema"<br />
  xmlns:t="http://www.nesterovsky-bros.com/xslt"<br />
  exclude-result-prefixes="xs t"&gt;<br /><br />
  &lt;xsl:template match="/"&gt;<br />
    &lt;xsl:variable name="value" as="xs:string"
select="'10100101'"/&gt;<br /><br />
    &lt;xsl:variable name="values" as="xs:integer+"
select="t:generate(1)"/&gt;<br /><br />
    &lt;!--&lt;xsl:variable name="values" as="xs:integer+"&gt;<br />
      &lt;xsl:call-template name="t:generate"&gt;<br />
        &lt;xsl:with-param name="value"
select="1"/&gt;<br />
      &lt;/xsl:call-template&gt;<br />
    &lt;/xsl:variable&gt;--&gt;<br /><br />
    &lt;xsl:variable name="integer" as="xs:integer"
select="<br />
      sum<br />
      (<br />
        for $index in 1 to string-length($value)
return<br />
          $values[$index][substring($value,
$index, 1) = '1']<br />
      )"/&gt;<br /><br />
    &lt;xsl:message select="$integer"/&gt;<br />
  &lt;/xsl:template&gt;<br /><br />
  &lt;xsl:function name="t:generate" as="xs:integer*"&gt;<br />
    &lt;xsl:param name="value" as="xs:integer"/&gt;<br /><br />
    &lt;xsl:sequence select="$value"/&gt;<br />
    &lt;xsl:sequence select="t:generate($value * 2)"/&gt;<br />
  &lt;/xsl:function&gt;<br /><br />
  &lt;!--&lt;xsl:template name="t:generate" as="xs:integer*"&gt;<br />
    &lt;xsl:param name="value" as="xs:integer"/&gt;<br /><br />
    &lt;xsl:sequence select="$value"/&gt;<br /><br />
    &lt;xsl:call-template name="t:generate"&gt;<br />
      &lt;xsl:with-param name="value" select="$value
* 2"/&gt;<br />
    &lt;/xsl:call-template&gt;<br />
  &lt;/xsl:template&gt;--&gt;<br /><br />
&lt;/xsl:stylesheet&gt;</code>
        </p>
        <p>
Here the logic uses such a generator and decides by itself where to break.
</p>
        <p>
Should such code be valid?
</p>
        <p>
From the algorithmic perspective example would better to work, as separation of generator
logic and its use are two different things.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=bc7a610a-31d5-40ac-aa6e-38e50c6ce932" />
      </body>
      <title>Generator functions in xslt</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,bc7a610a-31d5-40ac-aa6e-38e50c6ce932.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/04/09/GeneratorFunctionsInXslt.aspx</link>
      <pubDate>Fri, 09 Apr 2010 14:38:34 GMT</pubDate>
      <description>  &lt;p&gt;
By the generator we assume a function that produces an infinitive output sequence
for a particular input.
&lt;/p&gt;
&lt;p&gt;
That&amp;#39;s a rather theoretical question, as xslt does not allow infinitive sequence,
but look at the example:
&lt;/p&gt;
&lt;p class="style1" style="PADDING-LEFT: 1em"&gt;
&lt;code&gt;&amp;lt;xsl:stylesheet version=&amp;quot;2.0&amp;quot;&lt;br /&gt;
&amp;nbsp; xmlns:xsl=&amp;quot;http://www.w3.org/1999/XSL/Transform&amp;quot;&lt;br /&gt;
&amp;nbsp; xmlns:xs=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&lt;br /&gt;
&amp;nbsp; xmlns:t=&amp;quot;http://www.nesterovsky-bros.com/xslt&amp;quot;&lt;br /&gt;
&amp;nbsp; exclude-result-prefixes=&amp;quot;xs t&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:template match=&amp;quot;/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:variable name=&amp;quot;value&amp;quot; as=&amp;quot;xs:string&amp;quot;
select=&amp;quot;&amp;#39;10100101&amp;#39;&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:variable name=&amp;quot;values&amp;quot; as=&amp;quot;xs:integer+&amp;quot;
select=&amp;quot;t:generate(1)&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;!--&amp;lt;xsl:variable name=&amp;quot;values&amp;quot; as=&amp;quot;xs:integer+&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:call-template name=&amp;quot;t:generate&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:with-param name=&amp;quot;value&amp;quot;
select=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/xsl:call-template&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/xsl:variable&amp;gt;--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:variable name=&amp;quot;integer&amp;quot; as=&amp;quot;xs:integer&amp;quot;
select=&amp;quot;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sum&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for $index in 1 to string-length($value)
return&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $values[$index][substring($value,
$index, 1) = &amp;#39;1&amp;#39;]&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:message select=&amp;quot;$integer&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:function name=&amp;quot;t:generate&amp;quot; as=&amp;quot;xs:integer*&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:param name=&amp;quot;value&amp;quot; as=&amp;quot;xs:integer&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select=&amp;quot;$value&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select=&amp;quot;t:generate($value * 2)&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/xsl:function&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;!--&amp;lt;xsl:template name=&amp;quot;t:generate&amp;quot; as=&amp;quot;xs:integer*&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:param name=&amp;quot;value&amp;quot; as=&amp;quot;xs:integer&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select=&amp;quot;$value&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:call-template name=&amp;quot;t:generate&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:with-param name=&amp;quot;value&amp;quot; select=&amp;quot;$value
* 2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/xsl:call-template&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/xsl:template&amp;gt;--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/xsl:stylesheet&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Here the logic uses such a generator and decides by itself where to break.
&lt;/p&gt;
&lt;p&gt;
Should such code be valid?
&lt;/p&gt;
&lt;p&gt;
From the algorithmic perspective example would better to work, as separation of generator
logic and its use are two different things.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=bc7a610a-31d5-40ac-aa6e-38e50c6ce932" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,bc7a610a-31d5-40ac-aa6e-38e50c6ce932.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=76dd3ecd-c119-4ef4-b0ae-08b651778bcb</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,76dd3ecd-c119-4ef4-b0ae-08b651778bcb.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,76dd3ecd-c119-4ef4-b0ae-08b651778bcb.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=76dd3ecd-c119-4ef4-b0ae-08b651778bcb</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Lately, after playing a little with saxon tree models, we thought that design would
be more cleaner and implementation faster if <code>NamePool</code> were implemented
differently.
</p>
        <p>
Now, saxon is very pessimistic about java objects thus it prefers to encode qualified
names with integers. The encoding and decoding is done in the <code>NamePool</code>.
Other parts of code use these integer values.
</p>
        <p>
Operations done over these integers are: 
</p>
        <ul>
          <li>
equality comparision of two such integers in order to check whether to qualified or
extended names are equal;</li>
          <li>
get different parts of qualified name from <code>NamePool</code>.</li>
        </ul>
        <p>
We would design this differently. We would:
</p>
        <ol>
          <li>
create a <code>QualifiedName</code> class to store all name parts.</li>
          <li>
declare <code>NamePool</code> to create and cache <code>QualifiedName</code> instances.</li>
        </ol>
        <p>
This way:
</p>
        <ul>
          <li>
equality comparision would be a reference comparision of two instances;</li>
          <li>
different parts of qualified name would become a trivial getter;</li>
          <li>
contention of such name pool would be lower.</li>
        </ul>
        <p>
That's the implementation we would propose: <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=76dd3ecd-c119-4ef4-b0ae-08b651778bcb&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fsaxon%2fQualifiedName.java.txt"> QualifiedName.java</a>, <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=76dd3ecd-c119-4ef4-b0ae-08b651778bcb&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fsaxon%2fNameCache.java.txt"> NameCache.java</a></p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=76dd3ecd-c119-4ef4-b0ae-08b651778bcb" />
      </body>
      <title>Name pool</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,76dd3ecd-c119-4ef4-b0ae-08b651778bcb.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/04/09/NamePool.aspx</link>
      <pubDate>Fri, 09 Apr 2010 13:05:30 GMT</pubDate>
      <description>&lt;p&gt;
Lately, after playing a little with saxon tree models, we thought that design would
be more cleaner and implementation faster if &lt;code&gt;NamePool&lt;/code&gt; were implemented
differently.
&lt;/p&gt;
&lt;p&gt;
Now, saxon is very pessimistic about java objects thus it prefers to encode qualified
names with integers. The encoding and decoding is done in the &lt;code&gt;NamePool&lt;/code&gt;.
Other parts of code use these integer values.
&lt;/p&gt;
&lt;p&gt;
Operations done over these integers are: 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
equality comparision of two such integers in order to check whether to qualified or
extended names are equal;&lt;/li&gt;
&lt;li&gt;
get different parts of qualified name from &lt;code&gt;NamePool&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
We would design this differently. We would:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
create a &lt;code&gt;QualifiedName&lt;/code&gt; class to store all name parts.&lt;/li&gt;
&lt;li&gt;
declare &lt;code&gt;NamePool&lt;/code&gt; to create and cache &lt;code&gt;QualifiedName&lt;/code&gt; instances.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
This way:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
equality comparision would be a reference comparision of two instances;&lt;/li&gt;
&lt;li&gt;
different parts of qualified name would become a trivial getter;&lt;/li&gt;
&lt;li&gt;
contention of such name pool would be lower.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
That's the implementation we would propose: &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=76dd3ecd-c119-4ef4-b0ae-08b651778bcb&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fsaxon%2fQualifiedName.java.txt"&gt; QualifiedName.java&lt;/a&gt;, &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=76dd3ecd-c119-4ef4-b0ae-08b651778bcb&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fsaxon%2fNameCache.java.txt"&gt; NameCache.java&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=76dd3ecd-c119-4ef4-b0ae-08b651778bcb" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,76dd3ecd-c119-4ef4-b0ae-08b651778bcb.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=2a70d16f-cdd5-41c1-8fe3-ce5b58362d2a</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,2a70d16f-cdd5-41c1-8fe3-ce5b58362d2a.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,2a70d16f-cdd5-41c1-8fe3-ce5b58362d2a.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=2a70d16f-cdd5-41c1-8fe3-ce5b58362d2a</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Earlier, in the entry "<a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=2a70d16f-cdd5-41c1-8fe3-ce5b58362d2a&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2010%2f03%2f22%2fInlineFunctionsInXslt21.aspx">Inline
functions in xslt 2.1</a>" we've described an implementation of xml tree model
that may share subtrees among different trees.
</p>
        <p>
This way, in a code:
</p>
        <p style="padding-left: 1em">
          <code>&lt;xsl:variable name="elements" as="element()*" select="..."/&gt;<br /><br />
&lt;xsl:variable name="result" as="element()"&gt;<br />
  &lt;result&gt;<br />
    &lt;xsl:sequence select="$elements"/&gt;<br />
  &lt;/result&gt;<br />
&lt;/xsl:variable&gt;</code>
        </p>
        <p>
the implementation shares internal representation among <code>$elements</code> and
subtree of <code>$result</code>. From the perspective of xslt it looks as completely
different subtrees with different node identities, which is in the accordance with
its view of the world.
</p>
        <p>
After a short study we've decided to create a research implementation of this tree
model in saxon. It's took only a couple of days to introduce a minimal changes to
engine, to refactor linked tree into a new composable tree, and to perform some tests.
</p>
        <p>
In many cases saxon has benefited immediately from this new tree model, in some other
cases more tunings are required.
</p>
        <p>
Our tests've showed that this new tree performed better than linked tree, but a little
bit worser than tiny tree. On the other hand, it's obvious that conventional code
patterns avoid subtree copying, assuming it's expensive operation, thus one should
rethink some code practices to benefit from composable tree.
</p>
        <p>
Implementation can be downloaded at: <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=2a70d16f-cdd5-41c1-8fe3-ce5b58362d2a&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fsaxon.composabletree.zip"> saxon.composabletree.zip</a></p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=2a70d16f-cdd5-41c1-8fe3-ce5b58362d2a" />
      </body>
      <title>Composable tree model in saxon</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,2a70d16f-cdd5-41c1-8fe3-ce5b58362d2a.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/04/08/ComposableTreeModelInSaxon.aspx</link>
      <pubDate>Thu, 08 Apr 2010 06:26:02 GMT</pubDate>
      <description>&lt;p&gt;
Earlier, in the entry &amp;quot;&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=2a70d16f-cdd5-41c1-8fe3-ce5b58362d2a&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2010%2f03%2f22%2fInlineFunctionsInXslt21.aspx"&gt;Inline
functions in xslt 2.1&lt;/a&gt;&amp;quot; we've described an implementation of xml tree model
that may share subtrees among different trees.
&lt;/p&gt;
&lt;p&gt;
This way, in a code:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&amp;lt;xsl:variable name=&amp;quot;elements&amp;quot; as=&amp;quot;element()*&amp;quot; select=&amp;quot;...&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;xsl:variable name=&amp;quot;result&amp;quot; as=&amp;quot;element()&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;result&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select=&amp;quot;$elements&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/result&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:variable&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
the implementation shares internal representation among &lt;code&gt;$elements&lt;/code&gt; and
subtree of &lt;code&gt;$result&lt;/code&gt;. From the perspective of xslt it looks as completely
different subtrees with different node identities, which is in the accordance with
its view of the world.
&lt;/p&gt;
&lt;p&gt;
After a short study we've decided to create a research implementation of this tree
model in saxon. It's took only a couple of days to introduce a minimal changes to
engine, to refactor linked tree into a new composable tree, and to perform some tests.
&lt;/p&gt;
&lt;p&gt;
In many cases saxon has benefited immediately from this new tree model, in some other
cases more tunings are required.
&lt;/p&gt;
&lt;p&gt;
Our tests've showed that this new tree performed better than linked tree, but a little
bit worser than tiny tree. On the other hand, it&amp;#39;s obvious that conventional code
patterns avoid subtree copying, assuming it&amp;#39;s expensive operation, thus one should
rethink some code practices to benefit from composable tree.
&lt;/p&gt;
&lt;p&gt;
Implementation can be downloaded at: &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=2a70d16f-cdd5-41c1-8fe3-ce5b58362d2a&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fsaxon.composabletree.zip"&gt; saxon.composabletree.zip&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=2a70d16f-cdd5-41c1-8fe3-ce5b58362d2a" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,2a70d16f-cdd5-41c1-8fe3-ce5b58362d2a.aspx</comments>
      <category>Announce</category>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=bd644f94-7630-45b9-bca8-e27e42be7f04</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,bd644f94-7630-45b9-bca8-e27e42be7f04.aspx</pingback:target>
      <dc:creator>Arthur Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,bd644f94-7630-45b9-bca8-e27e42be7f04.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=bd644f94-7630-45b9-bca8-e27e42be7f04</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
From the web we know that xslt WG is thinking now on how to make xslt more friendly
to a huge documents. They will probably introduce some xslt syntax to allow implementation
to be ready for a such processing.
</p>
        <p>
They will probably introduce an indicator marking a specific mode for streaming. XPath
in this mode will probably be restricted to a some its subset.
</p>
        <p>
The funny part is that we have implemented similar feature back in 2002 in .net. It
was called <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=bd644f94-7630-45b9-bca8-e27e42be7f04&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fForwardNavigator.zip" target="_blank">XPathForwardOnlyNavigator</a>.
</p>
        <p>
Implementation stored only several nodes at a time (context node and its ancestors),
and read data from XmlReader perforce. Thus one could navigate to ancestor elements,
to children, and to the following siblings, but never to any previous node. When one
tried to reach a node that was already not available we threw an exception.
</p>
        <p>
It was simple, not perfect (too restrictive) but it was pluggable in .net's xslt,
and allowed to process files of any size.
</p>
        <p>
That old implementation looks very attractive even now in 2010. We expect that WG
with their decisions will not rule out such or similar solutions, and will not force
implementers to write alternative engine for xslt streaming.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=bd644f94-7630-45b9-bca8-e27e42be7f04" />
      </body>
      <title>How would we approach to streaming facility in xslt</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,bd644f94-7630-45b9-bca8-e27e42be7f04.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/04/04/HowWouldWeApproachToStreamingFacilityInXslt.aspx</link>
      <pubDate>Sun, 04 Apr 2010 20:53:27 GMT</pubDate>
      <description>&lt;p&gt;
From the web we know that xslt WG is thinking now on how to make xslt more friendly
to a huge documents. They will probably introduce some xslt syntax to allow implementation
to be ready for a such processing.
&lt;/p&gt;
&lt;p&gt;
They will probably introduce an indicator marking a specific mode for streaming. XPath
in this mode will probably be restricted to a some its subset.
&lt;/p&gt;
&lt;p&gt;
The funny part is that we have implemented similar feature back in 2002 in .net. It
was called &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=bd644f94-7630-45b9-bca8-e27e42be7f04&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fForwardNavigator.zip" target="_blank"&gt;XPathForwardOnlyNavigator&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Implementation stored only several nodes at a time (context node and its ancestors),
and read data from XmlReader perforce. Thus one could navigate to ancestor elements,
to children, and to the following siblings, but never to any previous node. When one
tried to reach a node that was already not available we threw an exception.
&lt;/p&gt;
&lt;p&gt;
It was simple, not perfect (too restrictive) but it was pluggable in .net's xslt,
and allowed to process files of any size.
&lt;/p&gt;
&lt;p&gt;
That old implementation looks very attractive even now in 2010. We expect that WG
with their decisions will not rule out such or similar solutions, and will not force
implementers to write alternative engine for xslt streaming.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=bd644f94-7630-45b9-bca8-e27e42be7f04" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,bd644f94-7630-45b9-bca8-e27e42be7f04.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=ee89adc6-d849-4a36-8736-a8ee3bf225b4</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,ee89adc6-d849-4a36-8736-a8ee3bf225b4.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,ee89adc6-d849-4a36-8736-a8ee3bf225b4.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=ee89adc6-d849-4a36-8736-a8ee3bf225b4</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Xslt 1.0 has been designed based on the best intentions. Xslt 2.0 got a legacy baggage.
</p>
        <p>
If you're not entirely concentrated during translation of your algorithms into
xslt 2.0 you can get into trap, as we did.
</p>
        <p>
Consider a code snapshot:
</p>
        <p style="padding-left: 1em;">
          <code>&lt;xsl:variable name="elements" as="element()+"&gt;<br />
  &lt;xsl:apply-templates/&gt;<br />
&lt;/xsl:variable&gt;<br /><br />
&lt;xsl:variable name="converted-elements" as="element()+"<br />
  select="$elements/t:convert(.)"/&gt; </code>
        </p>
        <p>
Looks simple, isn't it?
</p>
        <p>
Our intention was to get converted elements, which result from some <code>xsl:apply-templates</code> logic.
</p>
        <p>
Well, this code works... but rather sporadically, as results are often in wrong order!
This bug is very close to what is called a <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=ee89adc6-d849-4a36-8736-a8ee3bf225b4&amp;url=http%3a%2f%2fen.wikipedia.org%2fwiki%2fUnusual_software_bug%23Heisenbug">Heisenbug</a>.
</p>
        <p>
So, where is the problem?
</p>
        <p>
Elementary, my dear Watson:
</p>
        <ol>
          <li>
            <code>xsl:apply-templates</code> constructs a sequence of rootless elements.</li>
          <li>
            <code>$elements/t:convert(.)</code> converts elements and orders them in document
order.</li>
        </ol>
        <p>
Here is a tricky part:
</p>
        <p style="padding-left: 1em;">
          <i>The relative order of nodes in distinct trees is stable but implementation-dependent...</i>
        </p>
        <p>
Clearly each rootless element belongs to a unique tree.
</p>
        <p>
After that we have realized what the problem is, code has been immediately rewritten
as:
</p>
        <p style="padding-left: 1em;">
          <code>&lt;xsl:variable name="elements" as="element()+"&gt;<br />
  &lt;xsl:apply-templates/&gt;<br />
&lt;/xsl:variable&gt;<br /><br />
&lt;xsl:variable name="converted-elements" as="element()+" select="<br />
  for $element in $elements return<br />
    t:convert($element)"/&gt; </code>
        </p>
        <p>
P.S. Taking into an accout a size of our xslt code base, it took a half an hour to
localize the problem. Now, we're at position to review all uses of slashes in
xslt. As you like it?
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=ee89adc6-d849-4a36-8736-a8ee3bf225b4" />
      </body>
      <title>Xslt Heisenbug</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,ee89adc6-d849-4a36-8736-a8ee3bf225b4.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/04/02/XsltHeisenbug.aspx</link>
      <pubDate>Fri, 02 Apr 2010 17:53:18 GMT</pubDate>
      <description>&lt;p&gt;
Xslt 1.0 has been designed based on the best intentions. Xslt 2.0 got a legacy baggage.
&lt;/p&gt;
&lt;p&gt;
If you&amp;#39;re not entirely concentrated during translation of your algorithms into
xslt 2.0 you can get into trap, as we did.
&lt;/p&gt;
&lt;p&gt;
Consider a code snapshot:
&lt;/p&gt;
&lt;p style="padding-left: 1em;"&gt;
&lt;code&gt;&amp;lt;xsl:variable name="elements" as="element()+"&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:apply-templates/&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:variable&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;xsl:variable name="converted-elements" as="element()+"&lt;br /&gt;
&amp;nbsp; select="$elements/t:convert(.)"/&amp;gt; &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Looks simple, isn&amp;#39;t it?
&lt;/p&gt;
&lt;p&gt;
Our intention was to get converted elements, which result from some &lt;code&gt;xsl:apply-templates&lt;/code&gt; logic.
&lt;/p&gt;
&lt;p&gt;
Well, this code works... but rather sporadically, as results are often in wrong order!
This bug is very close to what is called a &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=ee89adc6-d849-4a36-8736-a8ee3bf225b4&amp;amp;url=http%3a%2f%2fen.wikipedia.org%2fwiki%2fUnusual_software_bug%23Heisenbug"&gt;Heisenbug&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
So, where is the problem?
&lt;/p&gt;
&lt;p&gt;
Elementary, my dear Watson:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;xsl:apply-templates&lt;/code&gt; constructs a sequence of rootless elements.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$elements/t:convert(.)&lt;/code&gt; converts elements and orders them in document
order.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Here is a tricky part:
&lt;/p&gt;
&lt;p style="padding-left: 1em;"&gt;
&lt;i&gt;The relative order of nodes in distinct trees is stable but implementation-dependent...&lt;/i&gt;
&lt;/p&gt;
&lt;p&gt;
Clearly each rootless element belongs to a unique tree.
&lt;/p&gt;
&lt;p&gt;
After that we have realized what the problem is, code has been immediately rewritten
as:
&lt;/p&gt;
&lt;p style="padding-left: 1em;"&gt;
&lt;code&gt;&amp;lt;xsl:variable name="elements" as="element()+"&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:apply-templates/&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:variable&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;xsl:variable name="converted-elements" as="element()+"&amp;nbsp;select="&lt;br /&gt;
&amp;nbsp; for $element in $elements return&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; t:convert($element)"/&amp;gt; &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
P.S. Taking into an accout a size of our xslt code base, it took a half an hour to
localize the problem. Now, we&amp;#39;re at position to review all uses of slashes in
xslt. As you like it?
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=ee89adc6-d849-4a36-8736-a8ee3bf225b4" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,ee89adc6-d849-4a36-8736-a8ee3bf225b4.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=c6c5519a-0df1-4a74-8f41-013c353a9470</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,c6c5519a-0df1-4a74-8f41-013c353a9470.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,c6c5519a-0df1-4a74-8f41-013c353a9470.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=c6c5519a-0df1-4a74-8f41-013c353a9470</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Opinions on xml namespaces
</p>
        <p style="indent-left: 1em">
          <i>
            <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=c6c5519a-0df1-4a74-8f41-013c353a9470&amp;url=http%3a%2f%2ftwitter.com%2folegtk%2fstatuses%2f11113278407">olegtk</a>:
@srivatsn Originally the idea was that namespace URI would point to some schema definition.
Long abandoned idea.</i>
        </p>
        <p>
Not so long ago, I've seen a good reasoning about the same subject:
</p>
        <ul>
          <li>
            <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=c6c5519a-0df1-4a74-8f41-013c353a9470&amp;url=http%3a%2f%2fblog.jclark.com%2f2010%2f01%2fxml-namespaces.html">XML
Namespaces</a> by James Clark;</li>
          <li>
            <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=c6c5519a-0df1-4a74-8f41-013c353a9470&amp;url=http%3a%2f%2fblog.jclark.com%2f2010%2f01%2fxml-namespaces.html%23c8143612790954715930">A
comment</a> by M. Kay.</li>
        </ul>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=c6c5519a-0df1-4a74-8f41-013c353a9470" />
      </body>
      <title>Xml namespaces</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,c6c5519a-0df1-4a74-8f41-013c353a9470.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/03/27/XmlNamespaces.aspx</link>
      <pubDate>Sat, 27 Mar 2010 09:49:45 GMT</pubDate>
      <description>&lt;p&gt;
Opinions on xml namespaces
&lt;/p&gt;
&lt;p style="indent-left: 1em"&gt;
&lt;i&gt;&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=c6c5519a-0df1-4a74-8f41-013c353a9470&amp;amp;url=http%3a%2f%2ftwitter.com%2folegtk%2fstatuses%2f11113278407"&gt;olegtk&lt;/a&gt;:
@srivatsn Originally the idea was that namespace URI would point to some schema definition.
Long abandoned idea.&lt;/i&gt;
&lt;/p&gt;
&lt;p&gt;
Not so long ago, I've seen a good reasoning about the same subject:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=c6c5519a-0df1-4a74-8f41-013c353a9470&amp;amp;url=http%3a%2f%2fblog.jclark.com%2f2010%2f01%2fxml-namespaces.html"&gt;XML
Namespaces&lt;/a&gt; by James Clark;&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=c6c5519a-0df1-4a74-8f41-013c353a9470&amp;amp;url=http%3a%2f%2fblog.jclark.com%2f2010%2f01%2fxml-namespaces.html%23c8143612790954715930"&gt;A
comment&lt;/a&gt; by M. Kay.&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=c6c5519a-0df1-4a74-8f41-013c353a9470" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,c6c5519a-0df1-4a74-8f41-013c353a9470.aspx</comments>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=baa5e955-a77d-41f4-8aef-a12fdb4625e5</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,baa5e955-a77d-41f4-8aef-a12fdb4625e5.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,baa5e955-a77d-41f4-8aef-a12fdb4625e5.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=baa5e955-a77d-41f4-8aef-a12fdb4625e5</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Inline functions in xslt 2.1 look often as a some strange aberration. Sure, there
are very usefull cases when they are delegates of program logic (e.g. comparators,
and filters), but often (probably more often) we can see that it's use is to model
data structures.
</p>
        <p>
As an example, suppose you want to model a structure with three properties say a,
b, and c. You implement this creating functions that wrap and unwrap the data:
</p>
        <p style="padding-left: 1em;">
          <code> function make-data($a as item(), $b as item(), $c as item()) as function()
as item()+<br />
{<br />
function() { $a, $b, $c } 
<br />
}</code>
        </p>
        <p style="padding-left: 1em;">
          <code> function a($data as function() as item()+) as item()<br />
{<br />
$data()[1]<br />
}</code>
        </p>
        <p style="padding-left: 1em;">
          <code> function b($data as function() as item()+) as item()<br />
{<br />
$data()[2]<br />
}</code>
        </p>
        <p style="padding-left: 1em;">
          <code> function c($data as function() as item()+) as item()<br />
{<br />
$data()[3]<br />
}</code>
        </p>
        <p>
Clever?
</p>
        <p>
Sure, it is! Here, we have modeled structrue with the help of sequence, which we have
wrapped into a function item.
</p>
        <p>
Alas, clever is not always good (often it's a sign of a bad). We just wanted to define
a simple structure. What it has in common with function?
</p>
        <p>
There is a distance between what we want to express, designing an algorithm, and what
we see looking at the code. The greater the distance, the more efforts are required
to write, and to read the code.
</p>
        <p>
It would be so good to have simpler way to express such concept as a structure. Let's
dream a little. Suppose you already have a structure, and just want to access its
members. An idea we can think about is an xpath like access method:
</p>
        <p style="padding-left: 1em;">
          <code> $data/a, $data/b, $data/c</code>
        </p>
        <p>
But wait a second, doesn't <code> $data</code> looks very like an xml element, and
its accessors are just node tests? That's correct, so data constructor may coincide
with element constructor.
</p>
        <p>
Then what pros and cons of using of xml elements to model structures?
</p>
        <p>
Pros are: existing xml type system, and sensibly looking code (you just understand
that here we're constructing a structure).
</p>
        <p>
Cons are: xml trees are implemented the way that does not assume fast (from the perfromace
perspective) composition, as when you construct a structure a copy of data is made. 
</p>
        <p>
But here we observe that "implemented" is very important word in this context. If
xml tree implementation would not store reference to the parent node then subtrees
could be composed very efficiently (note that tree is assumed to be immutable). Parent
node could be available through a tree navigator, which would contain reference to
a node itself and to a parent tree navigator (or to store child parent map somewhere
near the root).
</p>
        <p>
Such tree structure would probably help not only in this particular case but also
with other conventional xslt code patterns.
</p>
        <p>
P.S. Saxon probably could implement its <code>NodeInfo</code> this way.
</p>
        <p>
          <b>Update:</b> see also <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=baa5e955-a77d-41f4-8aef-a12fdb4625e5&amp;url=http%3a%2f%2fsourceforge.net%2fprojects%2fsaxon%2fforums%2fforum%2f94026%2ftopic%2f3644211">Custom
tree model</a>.
</p>
        <p>
          <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=baa5e955-a77d-41f4-8aef-a12fdb4625e5" />
        </p>
      </body>
      <title>Inline functions in xslt 2.1</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,baa5e955-a77d-41f4-8aef-a12fdb4625e5.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/03/22/InlineFunctionsInXslt21.aspx</link>
      <pubDate>Mon, 22 Mar 2010 11:02:07 GMT</pubDate>
      <description>&lt;p&gt;
Inline functions in xslt 2.1 look often as a some strange aberration. Sure, there
are very usefull cases when they are delegates of program logic (e.g. comparators,
and filters), but often (probably more often) we can see that it's use is to model
data structures.
&lt;/p&gt;
&lt;p&gt;
As an example, suppose you want to model a structure with three properties say a,
b, and c. You implement this creating functions that wrap and unwrap the data:
&lt;/p&gt;
&lt;p style="padding-left: 1em;"&gt;
&lt;code&gt; function make-data($a as item(), $b as item(), $c as item()) as function()
as item()+&lt;br /&gt;
{&lt;br /&gt;
function() { $a, $b, $c } 
&lt;br /&gt;
}&lt;/code&gt;
&lt;/p&gt;
&lt;p style="padding-left: 1em;"&gt;
&lt;code&gt; function a($data as function() as item()+) as item()&lt;br /&gt;
{&lt;br /&gt;
$data()[1]&lt;br /&gt;
}&lt;/code&gt;
&lt;/p&gt;
&lt;p style="padding-left: 1em;"&gt;
&lt;code&gt; function b($data as function() as item()+) as item()&lt;br /&gt;
{&lt;br /&gt;
$data()[2]&lt;br /&gt;
}&lt;/code&gt;
&lt;/p&gt;
&lt;p style="padding-left: 1em;"&gt;
&lt;code&gt; function c($data as function() as item()+) as item()&lt;br /&gt;
{&lt;br /&gt;
$data()[3]&lt;br /&gt;
}&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Clever?
&lt;/p&gt;
&lt;p&gt;
Sure, it is! Here, we have modeled structrue with the help of sequence, which we have
wrapped into a function item.
&lt;/p&gt;
&lt;p&gt;
Alas, clever is not always good (often it's a sign of a bad). We just wanted to define
a simple structure. What it has in common with function?
&lt;/p&gt;
&lt;p&gt;
There is a distance between what we want to express, designing an algorithm, and what
we see looking at the code. The greater the distance, the more efforts are required
to write, and to read the code.
&lt;/p&gt;
&lt;p&gt;
It would be so good to have simpler way to express such concept as a structure. Let's
dream a little. Suppose you already have a structure, and just want to access its
members. An idea we can think about is an xpath like access method:
&lt;/p&gt;
&lt;p style="padding-left: 1em;"&gt;
&lt;code&gt; $data/a, $data/b, $data/c&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
But wait a second, doesn't &lt;code&gt; $data&lt;/code&gt; looks very like an xml element, and
its accessors are just node tests? That's correct, so data constructor may coincide
with element constructor.
&lt;/p&gt;
&lt;p&gt;
Then what pros and cons of using of xml elements to model structures?
&lt;/p&gt;
&lt;p&gt;
Pros are: existing xml type system, and sensibly looking code (you just understand
that here we're constructing a structure).
&lt;/p&gt;
&lt;p&gt;
Cons are: xml trees are implemented the way that does not assume fast (from the perfromace
perspective) composition, as when you construct a structure a copy of data is made. 
&lt;/p&gt;
&lt;p&gt;
But here we observe that "implemented" is very important word in this context. If
xml tree implementation would not store reference to the parent node then subtrees
could be composed very efficiently (note that tree is assumed to be immutable). Parent
node could be available through a tree navigator, which would contain reference to
a node itself and to a parent tree navigator (or to store child parent map somewhere
near the root).
&lt;/p&gt;
&lt;p&gt;
Such tree structure would probably help not only in this particular case but also
with other conventional xslt code patterns.
&lt;/p&gt;
&lt;p&gt;
P.S. Saxon probably could implement its &lt;code&gt;NodeInfo&lt;/code&gt; this way.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;Update:&lt;/b&gt; see also &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=baa5e955-a77d-41f4-8aef-a12fdb4625e5&amp;amp;url=http%3a%2f%2fsourceforge.net%2fprojects%2fsaxon%2fforums%2fforum%2f94026%2ftopic%2f3644211"&gt;Custom
tree model&lt;/a&gt;.&lt;p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=baa5e955-a77d-41f4-8aef-a12fdb4625e5" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,baa5e955-a77d-41f4-8aef-a12fdb4625e5.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=dfc6287c-05ce-4bf2-9060-e0d93befd7ec</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,dfc6287c-05ce-4bf2-9060-e0d93befd7ec.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,dfc6287c-05ce-4bf2-9060-e0d93befd7ec.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=dfc6287c-05ce-4bf2-9060-e0d93befd7ec</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A while ago we have proposed to introduce maps as built-in types in xpath/xquery type
system: <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=dfc6287c-05ce-4bf2-9060-e0d93befd7ec&amp;url=http%3a%2f%2fwww.w3.org%2fBugs%2fPublic%2fshow_bug.cgi%3fid%3d5630">Tuples
and maps</a>.
</p>
        <p>
The suggestion has been declined (probably our arguments were not convincing). We,
however, still think that maps along with sequences are primitives, required to build
sensible (not obscure one) algorithms. To see that map is at times is the best way
to resolve the problems we shall refer to an utility function to allocate names in
scope. Its signature looks like this:
</p>
        <p style="padding-left: 1em">
          <code>&lt;!--<br />
Allocates unique names in the form $prefix{number}?.<br />
Note that prefixes may coincide. 
<br />
$prefixes - a name prefixes. 
<br />
$names - allocated names pool. 
<br />
$name-max-length - a longest allowable name length. 
<br />
Returns unique names.<br />
--&gt; 
<br />
&lt;xsl:function name="t:allocate-names" as="xs:string*"&gt; 
<br />
  &lt;xsl:param name="prefixes" as="xs:string*"/&gt; 
<br />
  &lt;xsl:param name="names" as="xs:string*"/&gt; 
<br />
  &lt;xsl:param name="name-max-length" as="xs:integer?"/&gt; </code>
        </p>
        <p>
Just try to program it and you will find yourselves coding something like one defined
at <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=dfc6287c-05ce-4bf2-9060-e0d93befd7ec&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fmisc%2fcobol-names.xslt">cobolxom</a>.
</p>
        <p>
To be efficient such maps should provide, at worst, a logarithmic operation complexity:
</p>
        <ul>
          <li>
Access to the map through a key (and/or by index) - complexity is LnN;</li>
          <li>
Creation of a new map with added or removed item - complexity is LnN;</li>
          <li>
Construction of the map from ordered items - complexity is O(N);</li>
          <li>
Construction of the map from unordered items - complexity is O(N*LnN);</li>
          <li>
Total enumeration of all items - complexity is O(N*LnN);</li>
        </ul>
        <p>
These performance metrics are found in many functional and procedural implementations
of the maps. Typical RB and AVL tree based maps satisfy these restrictions.
</p>
        <p>
What we suggest is to introduce map implementation into the exslt2 (assuming inline
functions are present). As a sketch we have implemented pure <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=dfc6287c-05ce-4bf2-9060-e0d93befd7ec&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2010%2f02%2f28%2fAVLTreeInXslt.aspx">AVL
Tree in Xslt 2.0</a>: 
</p>
        <ul>
          <li>
            <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=dfc6287c-05ce-4bf2-9060-e0d93befd7ec&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2ftree%2ftest.xslt"> test.xslt</a> -
a little test;</li>
          <li>
            <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=dfc6287c-05ce-4bf2-9060-e0d93befd7ec&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2ftree%2ftree.xslt"> tree.xslt</a> -
an AVL tree implementation;</li>
          <li>
            <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=dfc6287c-05ce-4bf2-9060-e0d93befd7ec&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2ftree%2ftuple.xslt"> tuple.xslt</a> -
a tuple interface and implementation.</li>
        </ul>
        <p>
We do not assume that implementation like this should be used, but rather think of
some extension function(s) that provides a better performance.
</p>
        <p>
What do you think?
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=dfc6287c-05ce-4bf2-9060-e0d93befd7ec" />
      </body>
      <title>Maps in exslt2?</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,dfc6287c-05ce-4bf2-9060-e0d93befd7ec.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/03/15/MapsInExslt2.aspx</link>
      <pubDate>Mon, 15 Mar 2010 13:59:19 GMT</pubDate>
      <description>&lt;p&gt;
A while ago we have proposed to introduce maps as built-in types in xpath/xquery type
system: &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=dfc6287c-05ce-4bf2-9060-e0d93befd7ec&amp;amp;url=http%3a%2f%2fwww.w3.org%2fBugs%2fPublic%2fshow_bug.cgi%3fid%3d5630"&gt;Tuples
and maps&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
The suggestion has been declined (probably our arguments were not convincing). We,
however, still think that maps along with sequences are primitives, required to build
sensible (not obscure one) algorithms. To see that map is at times is the best way
to resolve the problems we shall refer to an utility function to allocate names in
scope. Its signature looks like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&amp;lt;!--&lt;br /&gt;
Allocates unique names in the form $prefix{number}?.&lt;br /&gt;
Note that prefixes may coincide. 
&lt;br /&gt;
$prefixes - a name prefixes. 
&lt;br /&gt;
$names - allocated names pool. 
&lt;br /&gt;
$name-max-length - a longest allowable name length. 
&lt;br /&gt;
Returns unique names.&lt;br /&gt;
--&amp;gt; 
&lt;br /&gt;
&amp;lt;xsl:function name="t:allocate-names" as="xs:string*"&gt; 
&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:param name="prefixes" as="xs:string*"/&gt; 
&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:param name="names" as="xs:string*"/&gt; 
&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:param name="name-max-length" as="xs:integer?"/&gt; &lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
Just try to program it and you will find yourselves coding something like one defined
at &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=dfc6287c-05ce-4bf2-9060-e0d93befd7ec&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fmisc%2fcobol-names.xslt"&gt;cobolxom&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
To be efficient such maps should provide, at worst, a logarithmic operation complexity:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Access to the map through a key (and/or by index) - complexity is LnN;&lt;/li&gt;
&lt;li&gt;
Creation of a new map with added or removed item - complexity is LnN;&lt;/li&gt;
&lt;li&gt;
Construction of the map from ordered items - complexity is O(N);&lt;/li&gt;
&lt;li&gt;
Construction of the map from unordered items - complexity is O(N*LnN);&lt;/li&gt;
&lt;li&gt;
Total enumeration of all items - complexity is O(N*LnN);&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
These performance metrics are found in many functional and procedural implementations
of the maps. Typical RB and AVL tree based maps satisfy these restrictions.
&lt;/p&gt;
&lt;p&gt;
What we suggest is to introduce map implementation into the exslt2 (assuming inline
functions are present). As a sketch we have implemented pure &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=dfc6287c-05ce-4bf2-9060-e0d93befd7ec&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2010%2f02%2f28%2fAVLTreeInXslt.aspx"&gt;AVL
Tree in Xslt 2.0&lt;/a&gt;: 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=dfc6287c-05ce-4bf2-9060-e0d93befd7ec&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2ftree%2ftest.xslt"&gt; test.xslt&lt;/a&gt; -
a little test;&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=dfc6287c-05ce-4bf2-9060-e0d93befd7ec&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2ftree%2ftree.xslt"&gt; tree.xslt&lt;/a&gt; -
an AVL tree implementation;&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=dfc6287c-05ce-4bf2-9060-e0d93befd7ec&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2ftree%2ftuple.xslt"&gt; tuple.xslt&lt;/a&gt; -
a tuple interface and implementation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
We do not assume that implementation like this should be used, but rather think of
some extension function(s) that provides a better performance.
&lt;/p&gt;
&lt;p&gt;
What do you think?
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=dfc6287c-05ce-4bf2-9060-e0d93befd7ec" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,dfc6287c-05ce-4bf2-9060-e0d93befd7ec.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=1c5bfc72-d817-4916-b85e-e90e6bc498b7</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,1c5bfc72-d817-4916-b85e-e90e6bc498b7.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,1c5bfc72-d817-4916-b85e-e90e6bc498b7.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=1c5bfc72-d817-4916-b85e-e90e6bc498b7</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The story about immutable tree would not be complete without xslt implementation.
To make it possible one needs something to approxomate tree nodes. You cannot implement
such consruct efficiently in pure xslt 2.0 (it would be either unefficient or not
pure).
</p>
        <p>
To isolate the problem we have used tuple interface:
</p>
        <ul>
          <li>
            <code>tuple:ref($items as item()*) as item()</code> - to wrap items into a tuple;</li>
          <li>
            <code>tuple:deref($tuple as item()?) as item()*</code> - to unwrap items from a tuple;</li>
          <li>
            <code>tuple:is-same($first as item(), $second as item()) as xs:boolean</code> - to
test whether two tuples are the same.</li>
        </ul>
        <p>
and defined inefficient implementation based on xml elements. Every other part of
code is a regular AVL algorithm implementation.
</p>
        <p>
We want to stress again that even assuming that there is a good tuple implementation
we would prefer built-in associative container implementation. Why the heck you need
to include about 1000 lines of code just to use a map?
</p>
        <p>
Source code is:
</p>
        <ul>
          <li>
            <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=1c5bfc72-d817-4916-b85e-e90e6bc498b7&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2ftree%2ftest.xslt">test.xslt</a> -
a little test;</li>
          <li>
            <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=1c5bfc72-d817-4916-b85e-e90e6bc498b7&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2ftree%2ftree.xslt">tree.xslt</a> -
an AVL tree implementation;</li>
          <li>
            <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=1c5bfc72-d817-4916-b85e-e90e6bc498b7&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2ftree%2ftuple.xslt">tuple.xslt</a> -
a tuple interface and implementation.</li>
        </ul>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=1c5bfc72-d817-4916-b85e-e90e6bc498b7" />
      </body>
      <title>AVL Tree in Xslt</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,1c5bfc72-d817-4916-b85e-e90e6bc498b7.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/02/28/AVLTreeInXslt.aspx</link>
      <pubDate>Sun, 28 Feb 2010 19:28:07 GMT</pubDate>
      <description>&lt;p&gt;
The story about immutable tree would not be complete without xslt implementation.
To make it possible one needs something to approxomate tree nodes. You cannot implement
such consruct efficiently in pure xslt 2.0 (it would be either unefficient or not
pure).
&lt;/p&gt;
&lt;p&gt;
To isolate the problem we have used tuple interface:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;tuple:ref($items as item()*) as item()&lt;/code&gt; - to wrap items into a tuple;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tuple:deref($tuple as item()?) as item()*&lt;/code&gt; - to unwrap items from a tuple;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tuple:is-same($first as item(), $second as item()) as xs:boolean&lt;/code&gt; - to
test whether two tuples are the same.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
and defined inefficient implementation based on xml elements. Every other part of
code is a regular AVL algorithm implementation.
&lt;/p&gt;
&lt;p&gt;
We want to stress again that even assuming that there is a good tuple implementation
we would prefer built-in associative container implementation. Why the heck you need
to include about 1000 lines of code just to use a map?
&lt;/p&gt;
&lt;p&gt;
Source code is:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=1c5bfc72-d817-4916-b85e-e90e6bc498b7&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2ftree%2ftest.xslt"&gt;test.xslt&lt;/a&gt; -
a little test;&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=1c5bfc72-d817-4916-b85e-e90e6bc498b7&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2ftree%2ftree.xslt"&gt;tree.xslt&lt;/a&gt; -
an AVL tree implementation;&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=1c5bfc72-d817-4916-b85e-e90e6bc498b7&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2ftree%2ftuple.xslt"&gt;tuple.xslt&lt;/a&gt; -
a tuple interface and implementation.&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=1c5bfc72-d817-4916-b85e-e90e6bc498b7" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,1c5bfc72-d817-4916-b85e-e90e6bc498b7.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=28a0a8a6-ac66-466f-825d-873b62e4feec</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,28a0a8a6-ac66-466f-825d-873b62e4feec.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,28a0a8a6-ac66-466f-825d-873b62e4feec.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=28a0a8a6-ac66-466f-825d-873b62e4feec</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We like Visual Studio very much, and try to adopt new version earlier.
</p>
        <p>
For the last time our VS's use pattern is centered around xml and xslt. In our opinion
VS 2008 is the best xslt 2 editor we have ever seen even with lack of support of xslt
2.0 debugging.
</p>
        <p>
Unfortunatelly, that is still a true when VS 2010 is almost out. VS 2008 is just 2
- 3 times faster. You can observe this working with xslt files like those in <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=28a0a8a6-ac66-466f-825d-873b62e4feec&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip">languages-xom.zip</a> (1000
- 2000 rows). Things just become slow.
</p>
        <p>
We still hope that VS 2010 will make a final effort to outdo what VS 2008 has already
delivered.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=28a0a8a6-ac66-466f-825d-873b62e4feec" />
      </body>
      <title>VS 2010, Still Beta</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,28a0a8a6-ac66-466f-825d-873b62e4feec.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/02/28/VS2010StillBeta.aspx</link>
      <pubDate>Sun, 28 Feb 2010 18:37:58 GMT</pubDate>
      <description>&lt;p&gt;
We like Visual Studio very much, and try to adopt new version earlier.
&lt;/p&gt;
&lt;p&gt;
For the last time our VS's use pattern is centered around xml and xslt. In our opinion
VS 2008 is the best xslt 2 editor we have ever seen even with lack of support of xslt
2.0 debugging.
&lt;/p&gt;
&lt;p&gt;
Unfortunatelly, that is still a true when VS 2010 is almost out. VS 2008 is just 2
- 3 times faster. You can observe this working with xslt files like those in &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=28a0a8a6-ac66-466f-825d-873b62e4feec&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip"&gt;languages-xom.zip&lt;/a&gt; (1000
- 2000 rows). Things just become slow.
&lt;/p&gt;
&lt;p&gt;
We still hope that VS 2010 will make a final effort to outdo what VS 2008 has already
delivered.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=28a0a8a6-ac66-466f-825d-873b62e4feec" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,28a0a8a6-ac66-466f-825d-873b62e4feec.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=0de88938-0a18-45cd-b2ad-5fdf71d0aad8</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,0de88938-0a18-45cd-b2ad-5fdf71d0aad8.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,0de88938-0a18-45cd-b2ad-5fdf71d0aad8.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=0de88938-0a18-45cd-b2ad-5fdf71d0aad8</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
While bemoaning about lack of associative containers in xpath type system, we have
came up with a good implementation of t:allocate-names(). Implementation can be seen
at location <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=0de88938-0a18-45cd-b2ad-5fdf71d0aad8&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fmisc%2fcobol-names.xslt"> cobol-names.xslt</a>.
</p>
        <p>
It is based on recursion and on the use of xsl:for-each-group. Alogrithmic worst case
complexity is O(N*LogN*LogL), where N is number of names, and L is a length of a longest
name.
</p>
        <p>
This does not invalidate the idea that associative containers are very wishful, as
blessed one who naturally types such implementation. For us, it went the hard way,
and has taken three days to realize that original algorithm is problematic, and to
work out the better one.
</p>
        <p>
In practice this means 2 seconds for the new implementation against 25 minutes for
the old one.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=0de88938-0a18-45cd-b2ad-5fdf71d0aad8" />
      </body>
      <title>t:allocate-names() implementation</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,0de88938-0a18-45cd-b2ad-5fdf71d0aad8.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/02/25/tallocatenamesImplementation.aspx</link>
      <pubDate>Thu, 25 Feb 2010 07:19:06 GMT</pubDate>
      <description>&lt;p&gt;
While bemoaning about lack of associative containers in xpath type system, we have
came up with a good implementation of t:allocate-names(). Implementation can be seen
at location &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=0de88938-0a18-45cd-b2ad-5fdf71d0aad8&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2fmisc%2fcobol-names.xslt"&gt; cobol-names.xslt&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
It is based on recursion and on the use of xsl:for-each-group. Alogrithmic worst case
complexity is O(N*LogN*LogL), where N is number of names, and L is a length of a longest
name.
&lt;/p&gt;
&lt;p&gt;
This does not invalidate the idea that associative containers are very wishful, as
blessed one who naturally types such implementation. For us, it went the hard way,
and has taken three days to realize that original algorithm is problematic, and to
work out the better one.
&lt;/p&gt;
&lt;p&gt;
In practice this means 2 seconds for the new implementation against 25 minutes for
the old one.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=0de88938-0a18-45cd-b2ad-5fdf71d0aad8" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,0de88938-0a18-45cd-b2ad-5fdf71d0aad8.aspx</comments>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=74a4bf7e-caba-4e58-8319-cb43fd5c87e5</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,74a4bf7e-caba-4e58-8319-cb43fd5c87e5.aspx</pingback:target>
      <dc:creator>Arthur Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,74a4bf7e-caba-4e58-8319-cb43fd5c87e5.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=74a4bf7e-caba-4e58-8319-cb43fd5c87e5</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Why do we return to <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=74a4bf7e-caba-4e58-8319-cb43fd5c87e5&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2010%2f01%2f27%2fAssociativeContainersInAFunctionalLanguages.aspx">this
theme</a> again?
</p>
        <p>
Well, it's itching!
</p>
        <p>
In <a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=74a4bf7e-caba-4e58-8319-cb43fd5c87e5&amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip">cobolxom</a> there
is an utility function to allocate names in scope. Its signature looks like this:
</p>
        <p style="PADDING-LEFT: 1em">
          <code>&lt;!--<br />
  Allocates unique names in the form $prefix{number}?.<br />
  Note that prefixes may coincide. 
<br />
    $prefixes - a name prefixes. 
<br />
    $names - allocated names pool. 
<br />
    $name-max-length - a longest allowable name length. 
<br />
    Returns unique names.<br />
--&gt; 
<br />
&lt;xsl:function name="t:allocate-names" as="xs:string*"&gt; 
<br />
  &lt;xsl:param name="prefixes" as="xs:string*"/&gt; 
<br />
  &lt;xsl:param name="names" as="xs:string*"/&gt; 
<br />
  &lt;xsl:param name="name-max-length" as="xs:integer?"/&gt; </code>
        </p>
        <p>
We have created several different implementations (all use recursion). Every implementation
works fair for relatively small input sequences, say N &lt; 100, but we have cases
when there are about 10000 items on input. Algorithm's worst case complexity, in absence
of associative containers, is O(N*N), and be sure it's an O-o-o-oh... due to xslt
engine implementation.
</p>
        <p>
If there were associative containers with efficient access (complexity is O(LogN)),
and construction of updated container (complexity is also O(LogN)) then implementation
would be straightforward and had complexity O(N*LogN).
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=74a4bf7e-caba-4e58-8319-cb43fd5c87e5" />
      </body>
      <title>Again on immutable binary trees</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,74a4bf7e-caba-4e58-8319-cb43fd5c87e5.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2010/02/24/AgainOnImmutableBinaryTrees.aspx</link>
      <pubDate>Wed, 24 Feb 2010 07:34:07 GMT</pubDate>
      <description>&lt;p&gt;
Why do we return to &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=74a4bf7e-caba-4e58-8319-cb43fd5c87e5&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fweblog%2f2010%2f01%2f27%2fAssociativeContainersInAFunctionalLanguages.aspx"&gt;this
theme&lt;/a&gt; again?
&lt;/p&gt;
&lt;p&gt;
Well, it's itching!
&lt;/p&gt;
&lt;p&gt;
In &lt;a href="http://www.nesterovsky-bros.com/weblog/ct.ashx?id=74a4bf7e-caba-4e58-8319-cb43fd5c87e5&amp;amp;url=http%3a%2f%2fwww.nesterovsky-bros.com%2fdownload%2flanguages-xom.zip"&gt;cobolxom&lt;/a&gt; there
is an utility function to allocate names in scope. Its signature looks like this:
&lt;/p&gt;
&lt;p style="PADDING-LEFT: 1em"&gt;
&lt;code&gt;&amp;lt;!--&lt;br&gt;
&amp;nbsp; Allocates unique names in the form $prefix{number}?.&lt;br&gt;
&amp;nbsp; Note that prefixes may coincide. 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; $prefixes - a name prefixes. 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; $names - allocated names pool. 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; $name-max-length - a longest allowable name length. 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Returns unique names.&lt;br&gt;
--&amp;gt; 
&lt;br&gt;
&amp;lt;xsl:function name="t:allocate-names" as="xs:string*"&amp;gt; 
&lt;br&gt;
&amp;nbsp; &amp;lt;xsl:param name="prefixes" as="xs:string*"/&amp;gt; 
&lt;br&gt;
&amp;nbsp; &amp;lt;xsl:param name="names" as="xs:string*"/&amp;gt; 
&lt;br&gt;
&amp;nbsp; &amp;lt;xsl:param name="name-max-length" as="xs:integer?"/&amp;gt; &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
We have created several different implementations (all use recursion). Every implementation
works fair for relatively small input sequences, say N &amp;lt; 100, but we have cases
when there are about 10000 items on input. Algorithm's worst case complexity, in absence
of associative containers, is O(N*N), and be sure it's an O-o-o-oh... due to xslt
engine implementation.
&lt;/p&gt;
&lt;p&gt;
If there were associative containers with efficient access (complexity is O(LogN)),
and construction of updated container (complexity is also O(LogN)) then implementation
would be straightforward and had complexity O(N*LogN).
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=74a4bf7e-caba-4e58-8319-cb43fd5c87e5" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,74a4bf7e-caba-4e58-8319-cb43fd5c87e5.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
  </channel>
</rss>