I had to do this again today because of my hard drive crash, so I’ll document it here in case I have to do it again in the future.
Due to the relatively poor integration of GUI tools for Subversion (I consider them a leaky abstraction) with the command line version, I only use the command line for most of the actions. Still, I can’t stand the diff output generated by subversion.
It’s not hard to plug in a different diff tool like SourceGear’s Vault Diff and Merge into subversion. Here are the steps:
- create a batch file called diff.cmd and put it somewhere in your path; the contents of this file should be a single line: <path_to_vault_directory>\sgdm.exe %6 %7
- go to %AppData%\Subversion folder and open config file (it has no extension) in notepad (or suitable replacement); then search for diff-cmd = … and replace right hand side with diff.cmd
- enjoy!
Be the first to rate this post
- Currently 0/5 Stars.
- 1
- 2
- 3
- 4
- 5
I wrote about books on the Windows Presentation Foundation (WPF from now on) before. I am one of those that thinks WPF is significant for all Windows developers. Once Microsoft sets the standard with WPF, I am sure other vendors will follow and WPF (or a variant of it) will become significant for developers on other platforms too.
Quite some time ago, I bought and read Chris Sells’ and Ian Griffiths’ WPF book. It was good and I liked it. Chris Andersons’ book is still in the finishing stages, but Petzold’s book is just out. Charles Petzold is a legend in Windows world, most of the developers I know learned Windows programming (using C/C++ and the Win32 API) from his book.
Well, I am happy to report that Charles’ book Application = Markup + Code is great. Unlike Sells’ book that mainly deals with markup (XAML), Charles spends half of the book using just C# code to produce WPF apps. It makes sense to focus more on XAML as it is less familiar to the average C# developer. However, showing you C# code gives you great second perspective on the way WPF works and if anything, after seeing long and convoluted segments of code that prepare control templates, you will only appreciate XAML’s terseness more.
You don’t have to have a book to evaluate it! The code samples are available and they work with RC1 release of Windows Vista and .NET 3.0 runtime (that has to be installed on Windows XP machines). Check them out – they’re great. The book is very long, but there’s a lot of code inside and the topics get more complicated progressively and slowly. The approach is much alike bottom-up – larger blocks of functionality get built from smaller ones.
Charles builds several useful WPF utilities during the course of the book but I find his “Dump Control Template” the best – not only have I not seen anything like it from other authors, the utility is extremely useful: it shows you exactly how Microsoft built the “built-in” controls like slider (on the picture to the right, quite a complicated one!), progress bar, button…
If for some reason you must choose only one book on WPF, you should choose Petzold’s. Otherwise, buy them all (I know I will). As I’ve said before, it’ll take some time until this technology sinks in and you’ll need all the help you can get.
Be the first to rate this post
- Currently 0/5 Stars.
- 1
- 2
- 3
- 4
- 5
Hey, I’m lazy – I still run this blog on an ancient (in Internet time) version of the .Text blogging engine. In fact, I wanted to “upgrade” to Community Server (CS) at least twice, but the conversion process has not been as smooth as I’d want it to, plus the configuration is generally a nightmare if you have only a single blog and don’t want or need the rest of the CS features.
The other reason is that I’ve already integrated two “plug-ins” in the .Text that would most likely require some work to fit into the CS and here I am - still running 3 years old codebase. Having this in mind the .Text engine works surprisingly well…
Back to the point: if you’ve tried Internet Explorer 7, you have noticed that going to the RSS feed directly presents a nice HTML page rather than a plain XML view Internet Explorer 6 shows. The screenshot to the left shows my feed inside the Internet Explorer 7 beta 3. Note two things – you can sort entries by more than just a date and you can filter posts by the category. I have clicked on a Ruby category and got back 3 posts out of 10.
Filtering by category does not work by default with the .Text. The reason is trivial – for some reason even though the .Text supports categories they are not listed for each post in the main feed.
You can subscribe to a separate category or look at the posts only for a separate category, but the main feed will not contain them. It’s trivial to fix this though assuming you still have a copy of Visual Studio 2003 around – download the source code of the .Text project, and add the highlighted lines to Syndication\BaseRssWriter.cs in the Dottext.Framework project:
protected virtual void EntryXml(Entry entry, BlogConfigurationSettings settings, UrlFormats uformat)
{
this.WriteElementString("dc:creator",entry.Author);
//core
this.WriteElementString("title",entry.Title);
//core
this.WriteElementString("link",entry.Link);
this.WriteElementString("pubDate",entry.DateCreated.ToString("r"));
//core Should we set the
this.WriteElementString("guid",entry.Link);
// emit categories too
CategoryEntry ce = Dottext.Framework.Entries.GetCategoryEntry(entry.EntryID, true);
if(null != ce)
{
foreach(String category in ce.Categories)
WriteElementString("category", category);
}
// rest of the method...
}
Took me just a few minutes to find the right place and fix this because the code is very readable – well done Scott!
Be the first to rate this post
- Currently 0/5 Stars.
- 1
- 2
- 3
- 4
- 5
I have a huge respect for Miguel de Icaza. He’s the guy that almost single-handedly reimplemented huge chunks of the .NET compiler, the runtime and the pieces of the class libraries – see the Mono project.
But his remark from a few days ago, while catchy, is way off the mark. He said, and I quote:
Microsoft's Avalon is the J2EE of GUI APIs.
I don’t believe Miguel has spent enough time with Avalon to make witty remarks like this. If he did, there’s no way he would think this way.
Contrast his remark with what Eric Sink had to say on the matter, in several blog posts while actually building something. (I won’t link to all posts, but just search for “WPF” and you’ll find them all)
As soon as I start actively working on the GUI of my app, I will have more to say. I know that I will be using Avalon and find it far superior to anything else (on Windows!) including WinForms.
Be the first to rate this post
- Currently 0/5 Stars.
- 1
- 2
- 3
- 4
- 5
The success of AJAX and Ruby on Rails points out at another small “revolution” going on for the Web applications – the change in the underlying markup language used to shuffle data back and forth. Classic examples are YAML and JSON. A little bit of history on both and an inspiration for this blog post is here: JSON on the Web, or: The Revenge of SML.
I generally agree with the points presented in the article but I have a thing or two to add. Both YAML and JSON are pretty much specialized object serialization formats – the former for Ruby and the latter for JavaScript. In theory, they could be used for other languages too, but in practice these are the two places where they are used.
It all makes perfect sense. If what you are trying to do is to serialize and deserialize an object graph, round-tripping through the XML might not be the best thing to do. It’s not too hard to design a specialized format that will cover your needs better than an equivalent XML, where better is usually defined as faster to parse, easier to read (by a human) and more compact, as long as you narrow the scope enough.
But the point is that this does not make XML any worse than it is. I see XML as an interchange format between different operating systems, machines and different programming languages. XML is often used as a format for a DSL (domain specific language). It may not fit hundreds of tasks very well, but it will fit thousands good enough.
The XML is never (and I postulate it never was) a be-all solution to various kinds of problems. Here’s an example – since Ant, we have seen several build systems (libraries that help you build your code) based on XML, one of the latest being Microsoft’s (quite well thought out) MsBuild. All these build systems are easy to author, easy to read and work really well. One would think that all has been said an done regarding build systems (using current generation tools and languages). But then rake came out and changed everything. Instead of “interpreting” or deserializing the build DSL (expressed as XML) the DSL is embedded in the host language (Ruby). The integration works even better than Ant and MsBuild IMHO. For a really thorough and well-written discussion check out this article by Martin Fowler: Using the Rake Build Language.
The way I see it, JSON, YAML and XML will continue to co-exist; we may even see the proliferation of other specialized languages. That does not make any of them better or worse than the other – they are not here to compete, but each to be used well in its problem domain.
Be the first to rate this post
- Currently 0/5 Stars.
- 1
- 2
- 3
- 4
- 5
For years I was hearing from my brother and other Web developers how crappy Internet Explorer’s CSS support has been. Broken box model, extra margins and paddings, wrong font sizes… All this time I thought – so what's the fuss? A few broken rules here and there, so what?
Well, after building a relatively small database driven site in ASP.NET 2.0 and having to style it too (not just do the coding) I can finally understand these people. I wouldn’t want anyone to have to face the struggle with Internet Explorer to respect your CSS. It is absolutely unbelievable how many small things do not work properly. It’s all minor if taken in isolation, but together… it’s a nightmare.
I can’t wait for Internet Explorer 7 to clean most of these things up and I pity all those poor souls who had to endure this madness over the years, especially in the early days. At least we have Firefox today to verify our sanity and understanding of the standards…
Be the first to rate this post
- Currently 0/5 Stars.
- 1
- 2
- 3
- 4
- 5
As some of you know, there is an ongoing discussion whether Microsoft should/will support XSLT 2.0 in the next iteration of the .NET framework. Apparently, there are not enough resources (?) to implement both XQuery 1.0 and XSLT 2.0 so for now it looks like the latter will be implemented as it can be (and will be) also used in the database scenarios (looks more like SQL and is used in the similar way).
XSLT 1.0 compiled transform in the .NET 2.0 absolutely rocks, so not having a similar thing for the XSLT 2.0 is a bummer. Note that I am talking about invoking transformer right from your code, not from the command line. You could use free Altova’s AltovaXML tools but my experiments show the XSLT 2.0 engine is not nearly as conformant as it should be (chokes on simple demo files). Saxonica’s Saxon is great, but it’s written in Java and command line is the only option.
Or should I say was the only option. Since very recently (about a month ago) the effort to port Saxon to the .NET platform has been moved under the wings of Saxonica (it used to be a community project). The port is far from perfect as it uses IKVM and some of the APIs have slightly weird naming – methods that should be called CreateXXX are called NewXXX for example, but… it works and some parts of it are based on the .NET FCL.
The documentation is fairly complete but the latest download does not contain the C# samples mentioned on the Saxonica’s web site. So if you want to see some samples (and you will need to, as I will show just now) download both the latest version 8.7.1 and the previous version 8.7 of the resources.
To save you the trouble, or if you just want to see how a typical transform would look like, here it is:
using Saxon.Api;
internal class Program
{
[STAThread]
private static void Main(string[] args)
{
string source = @"c:\temp\input.xml";
string xslt = @"c:\temp\transform.xslt";
string dest = @"c:\temp\output.txt";
Processor p = new Processor();
XsltCompiler xc = p.NewXsltCompiler();
xc.BaseUri = new Uri(xslt);
using (FileStream tfs = new FileStream(xslt, FileMode.Open,
FileAccess.Read, FileShare.Read))
using (FileStream ifs = new FileStream(source, FileMode.Open,
FileAccess.Read, FileShare.Read))
using (FileStream ofs = new FileStream(dest, FileMode.Create,
FileAccess.Write, FileShare.None))
{
XsltExecutable xe = xc.Compile(tfs);
XsltTransformer xt = xe.Load();
DocumentBuilder db = p.NewDocumentBuilder();
db.BaseUri = new Uri(source);
xt.InitialContextNode = db.Build(ifs);
Serializer s = new Serializer();
s.SetOutputStream(ofs);
xt.Run(s);
}
}
}
This code can be simplified – to most of the constructs you can provide file names directly and not bother with the streams (but in real life usage you might already have streams that you got from somewhere).
This is great news for the .NET developers looking forward to using XSLT 2.0 in their projects straight from their code.
Be the first to rate this post
- Currently 0/5 Stars.
- 1
- 2
- 3
- 4
- 5
For a long time I preferred Altova’s XMLSpy as an XSD editor. I especially like its graphical schema display – it shows the structure of your schema in a very intuitive way. However, I have recently discovered that Visual Studio 2005 is very capable XSD editor too, just not that much graphical.
While editing one of my XML files I decided to change the schema and didn’t want to leave the IDE so I just started typing directly in Visual Studio 2005 XML editor. It turns out that IDE XML validation goes way beyond what you would expect. I discovered this by adding a new type (a new element) that had the same name as one of the existing elements.
And then I got a very, very detailed and instructive warning – if you name two elements the same, and only change number/kind of attributes and number/nesting of inner elements, it makes parsing and validating such elements hard, because parser cannot deduce what the element is just by its name.
This is very cool. It’s not complicated to validate XSD rigidly according to its schema, but it’s definitely complicated/extra work to provide meaningful warnings like this one – hard to implement for IDE developers, but good and useful for us XML developers.
Be the first to rate this post
- Currently 0/5 Stars.
- 1
- 2
- 3
- 4
- 5
Last week Microsoft published the first beta of Interactive Designer (a.k.a. Sparkle) so now all those that fear angle brackets can edit XAML via nice GUI editor.
Or not. I took a project I had developed in Visual Studio 2005 and opened it up in Sparkle and as soon as I clicked on the main window the app crashed. Repeatedly. I think this is the first time I actually used the button on the crash dialog and sent crash report to Microsoft. I am genuinely interested in seeing this tool mature but for now I'll stick (unfortunately) to XAMLPad.
The markup that crashes Sparkle is not complicated and actually works fine when you start the application. Unlike Sparkle, Visual Studio is not even able to show the markup in design mode and complains about some obscure missing property or something like that.
Luckily (to me at least) Avalon is easy to code even by hand so I'll continue to do just that. But I definitely look forward to future releases of this or any other GUI editor.
Be the first to rate this post
- Currently 0/5 Stars.
- 1
- 2
- 3
- 4
- 5
Continuing the topic of my earlier post, Ben responds at the bottom of the post:
Drazen wrote a good response to me in Quick, which is better suited for XML transformation: C++ or XSLT? It is nicely presented, but I've got to say it ultimately only makes the point here stronger. It is significant that he uses "EXSLT" to get the power function he needed. Though he tried to preemptively defend this decision, it is an example of how you are at the mercy of your XSLT component to implement an extension, and it stops my MXSML 4.0 test from working. His new XSL is half the lines and if I remove the power function (and ignore the incorrect line numbers) it runs as fast as my C++ example. But it looks like the line numbering in his solution still depends on a certain number of elements as I gather from the 6 in math:power(6, count($recurse)), whereas my C++ example can have any number of col elements in any number of column elements. Sure he can fix that too, but the fact that someone skilled with XSLT can improve this particular stylesheet does not prove the value of XSLT for this problem.
Ben is right on almost all acounts - I did make an oversight and implemented the solution assuming that the number of child elements of column is equal for all elements (original post has been modified to mention this and provide the fix). I don't agree that using EXSLT is unfair - it's like complaining that if you used hash_map in your C++ app you are relying on an extension (even though all vendors provide this).
Nevertheless, let's see what the problem really is here. The stylesheet is more complicated and required power function only to work-around an inherent design issue of XSLT as a language without side-effects to variables - once set, you can't change variable's value but that's exactly what I need to implement a counter. If the problem did not require the result rows to be numbered, things would have worked out perfectly.
But let's see what I can do to fix the stylesheet as is, using something other than power and not using EXSLT. Due to the wrong assumption about number of child nodes of column element, I can't use power anyway. What I need to do is to compute the product of number of child elements following the current node. In order to do so, I'll change the line that computes the increment to this:
<xsl:variable name="increment">
<xsl:call-template name="product">
<xsl:with-param name="nodes" select="$recurse"/>
</xsl:call-template>
</xsl:variable>
But where is the mysterious product template? It's in the separate XSLT file - it's just a utility function that computes a product of a value of some nodes, where “value” is defined in terms of the template you provide. Think of templates here as functions that call each other to compute something. Here's the definition of product:
<xsl:template name="product">
<xsl:param name="nodes"/>
<xsl:param name="result" select="1"/>
<xsl:choose>
<xsl:when test="not($nodes)">
<xsl:value-of select="$result"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="value">
<xsl:call-template name="get-node-value">
<xsl:with-param name="node" select="$nodes[1]"/>
</xsl:call-template>
</xsl:variable>
<xsl:call-template name="product">
<xsl:with-param name="nodes" select="$nodes[position() != 1]"/>
<xsl:with-param name="result" select="$result * $value"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Aha, it's getting complicated, you might say. True, but again think of this as a general purpose utility function that is reusable for other purposes as well and can be included in any stylesheet. Otherwise I can dismiss Ben's C++ solution for using a custom string implementation instead of CString :) Note the get-node-value template it depends on - that's the “value“ of node I just talked about. In this case the template boils down to this (should be replaced with a different implementation for each distinct purpose):
<xsl:template name="get-node-value">
<xsl:param name="node"/>
<xsl:value-of select="count($node/*)"/>
</xsl:template>
The resulting complete template is only 6-7 lines longer than the original (not counting utility template product). But it's still complicated for the beginner, and Ben is right - simple problems like this should have simple solution. I wouldn't be telling you all this if I didn't have one, would I? :)) Let's look again at the real problem here - all I need is a simple counter. The only reason I bothered with power and product was to avoid counting. But there's another way to avoid counting too: two-pass solution. Don't worry - it is as performant as the original solution and a few lines shorter (complete source presented for completeness):
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ms="urn:schemas-microsoft-com:xslt">
<xsl:output method="text" omit-xml-declaration="yes" encoding="iso-8859-1"/>
<xsl:template match="columns">
<xsl:variable name="lines">
<xsl:apply-templates select="column[1]"/>
</xsl:variable>
<xsl:for-each select="ms:node-set($lines)/line">
<xsl:value-of select="concat(position(), .)"/>
</xsl:for-each>
</xsl:template>
<xsl:template match="column">
<xsl:param name="running" select="''"/>
<xsl:variable name="recurse" select="following-sibling::*"/>
<xsl:for-each select="col">
<xsl:variable name="current_running" select="concat($running, ' ', .)"/>
<xsl:if test="$recurse">
<xsl:apply-templates select="$recurse[1]">
<xsl:with-param name="running" select="$current_running"/>
</xsl:apply-templates>
</xsl:if>
<xsl:if test="not($recurse)">
<xsl:element name="line">
<xsl:value-of select="concat($current_running, ' ')"/>
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
First I create a temporary node set, and then output it out using the position of the nodes as a counter. I know - another extension (node-set). Hey, it works with MSXSL 4.0 so at least Ben shouldn't complain ;) Seriously, the only reason I am using the extension is because it is practically a mandatory extension for every decent XSLT processor as it rectifies what I consider a flawed spec for XSLT 1.0. The proof is in the XSLT 2.0 spec - if you remove the extension the stylesheet will work as-is with any 2.0 conformant XSLT processor (tried with Saxon).
I don't think this example proves that one should avoid XSLT. What is obvious though is that the mental shift required for an average developer when going from C++ to XSLT might indeed be too high. If you can't figure XSLT out, by all means use CMarkup or a similar library. But don't do it just because XSLT is different - there's value there too. If we'd all skip technologies and languages we are not familiar with we'd code most of the Web apps in assembler instead of PHP, Ruby or Python :)
Be the first to rate this post
- Currently 0/5 Stars.
- 1
- 2
- 3
- 4
- 5