Archive for July, 2008

“Erroring off?”

Wednesday, July 23rd, 2008

Has anyone told you that a program is “erroring off” or that some system “errored off?” Occasionally I have the pleasure of receiving such notices and every time it makes me cringe.

Let me explain something. “Error” is not a verb. You can’t error. It’s not possible. When you type “erroring” it has a red wavy underline for a reason.

You can err. “Erring off” is at least valid English, but I’m not sure what purpose the “off” serves. “Erring” works by itself.

Or you could just use one of the industry-standard terms, like

  • crashed,
  • failed,
  • went down, or
  • is unavailable.

As a bonus, most of these actually convey the nature of the problem. The only information “erroring off” conveys is that you not only don’t know exactly what went wrong, but also have a substandard grasp of the English language.

Website statistics

Monday, July 21st, 2008

About two weeks ago I started collecting statistics for this website, something I’ve always planned on doing but never actually cared enough to sit down and do. Two weeks doesn’t make for a great sample period but the results are still interesting.

Almost 25% of visitors use some version of IE and 44% use Firefox. (20% did not identify their browser.) This is rather astounding to me. Apparently either FF gained more market share than I thought or this blog tends to attract the kind of people who use FF (probably the latter). Mozilla, Opera, and Safari are straggling at 5.7%, 3.3%, and 1.4% respectively.

Out of the 25% using IE, the usage is almost exactly split between IE6 and IE7, with IE7 almost a full 1% ahead. Can someone please explain why people are still using IE6? Seriously people, this is 2008.

Firefox >= 3.0 accounts for a little over half of all FF traffic with various versions of 2.0 making up for most of the difference and a negligible amount of 1.0 and pre-1.0 hits making up the rest.

When it comes to operating systems, almost 54% are using Windows, 21% Linux, 3% Mac OS X, and 22% unidentified. Windows XP wins with 40% overall usage and Vista can claim 7%. Most of the Linux hits didn’t identify the distro.

The search robot report is interesting. From the major search engines, Google was the most conservative, making 236 hits for 2.83MB of data. MSN hit 975 times for 9.71MB. The winner is Yahoo: 2057 hits for a whopping 27MB. I’m not quite sure why Yahoo needs so much… Google seems to keep up just fine while consuming only a tenth of what Yahoo does.

Not surprisingly, the most popular blog posts are not about my own projects. The most viewed one by far was a gripe about gnome-terminal. Seems many people have the same irritation that I do.

So yeah. I don’t really have any point to make, except possibly that people should not be using IE6 anymore, and some search engines should really optimize their crawlers better.

Three-column CSS layout

Monday, July 7th, 2008

There are many established CSS layouts for doing a three-column website. They seem to work pretty well. Perhaps the most popular is the Faux Columns technique.

At work we are working on an internal site that requires three columns (or to be more precise, up to two sidebars). I have never been completely satisfied with the many existing three-column hacks so I decided to roll my own after laying out some requirements:

  • The unstyled page should look decent (primarily for mobile browsers). This includes having the sidebars come after the main content in the HTML source.
  • The sidebar backgrounds should extend down to the header, without using any background image tricks.
  • IE7 and FF2+ must render the layout correctly. Minor defects are ok in other browsers.

The sidebar backgrounds have always been the tricky part, but I have a non-image solution for IE7 and FF2+. It also works in Safari.

IE6 does not extend the background colors to the footer, but it does correctly position the sidebars at least. After a bit of hackery anyway. Apparently IE6 doesn’t correctly compute the correct X position for absolutely-positioned elements. left:0px was making the left sidebar overlap with the content. I replaced this with float:left and IE6 positioned it like the other browsers, and thankfully the other browsers continued to position it in the same place. So as a bonus, no IE conditional comments were required.

Anyway, here it is. I am releasing the CSS and HTML source to the public domain, but if you reuse the code a link to this post would be appreciated.

.NET and XPath

Tuesday, July 1st, 2008

So I’m working on this XPath presentation for my team at work. I was trying to hack up a sample using some of the more interesting XPath functions, like string-join. PHP’s DOMXPath throws a fit when I use this function so I cracked open MSDN and saw that XPathNavigator in the 2.0 framework claims to support “the XQuery 1.0 and XPath 2.0 Data Model[s].” Nifty, huh? Especially since string-join is defined in those specs. (Note that this table claims it is available in XPath 1.0. Apparently nobody bothered to check the XPath 1.0 specification which does not mention it at all.)

PHP’s implementation must be broken then. Off I go and code a Winforms project that I can use to run my example. Right? Yeah, right…

For the sake of simplicity, I coded a small CLI program that will run an XPath query against an empty document:

using System;
using System.Xml;
using System.Xml.XPath;

public class XPathCLI {
    public static void Main(string[] args) {
        XmlDocument doc = new XmlDocument();

        XPathNavigator nav = doc.CreateNavigator();
        Console.WriteLine(nav.Evaluate(args[0]).ToString());
    }
}

Now let’s make sure it’s working:

$ ./XPathCLI.exe 'concat("hello ", "world")'
hello world

Looks good. Now let’s try the examples listed under string-join:

$ ./XPathCLI.exe "string-join({'Now', 'is', 'the', 'time', '...'}, \" \")"

Unhandled Exception: System.Xml.XPath.XPathException: invalid token: '{'
  at Mono.Xml.XPath.Tokenizer.ParseToken () [0x00000]
  at Mono.Xml.XPath.Tokenizer.advance () [0x00000]
  at Mono.Xml.XPath.XPathParser.yyparse (yyInput yyLex) [0x00000]
  at Mono.Xml.XPath.XPathParser.Compile (System.String xpath) [0x00000]

$ ./XPathCLI.exe "string-join({abra, cadabra}, \"\")"

Unhandled Exception: System.Xml.XPath.XPathException: invalid token: '{'
  at Mono.Xml.XPath.Tokenizer.ParseToken () [0x00000]
  at Mono.Xml.XPath.Tokenizer.advance () [0x00000]
  at Mono.Xml.XPath.XPathParser.yyparse (yyInput yyLex) [0x00000]
  at Mono.Xml.XPath.XPathParser.Compile (System.String xpath) [0x00000]

$ ./XPathCLI.exe 'string-join((), "separator")'

Unhandled Exception: System.Xml.XPath.XPathException: Error during parse of string-join((), "separator") ---> Mono.Xml.XPath.yyParser.yyException: irrecoverable syntax error
  at Mono.Xml.XPath.XPathParser.yyparse (yyInput yyLex) [0x00000]
  at Mono.Xml.XPath.XPathParser.Compile (System.String xpath) [0x00000] --- End of inner exception stack trace ---

  at Mono.Xml.XPath.XPathParser.Compile (System.String xpath) [0x00000]
  at System.Xml.XPath.XPathExpression.Compile (System.String xpath, IXmlNamespaceResolver nsmgr, IStaticXsltContext ctx) [0x00000]
  at System.Xml.XPath.XPathExpression.Compile (System.String xpath) [0x00000]
  at System.Xml.XPath.XPathNavigator.Compile (System.String xpath) [0x00000]
  at System.Xml.XPath.XPathNavigator.Evaluate (System.String xpath) [0x00000]
  at XPathCLI.Main (System.String[] args) [0x00000]

Ok, that didn’t go too well. Apparently Mono doesn’t like some of the syntax. Let’s use a node selecting expression instead:

$ ./XPathCLI.exe 'string-join(//something, "separator")'

Unhandled Exception: System.Xml.XPath.XPathException: function string-join not found
  at System.Xml.XPath.ExprFunctionCall.Evaluate (System.Xml.XPath.BaseIterator iter) [0x00000]
  at System.Xml.XPath.CompiledExpression.Evaluate (System.Xml.XPath.BaseIterator iter) [0x00000]

Uh… ok. Let’s start over on MS.NET. It must be a Mono bug, right?

>XPathCLI.exe "string-join({'Now', 'is' 'the', 'time', '...'}, \" \")"

Unhandled Exception: System.Xml.XPath.XPathException: 'string-join({'Now', 'is''the', 'time', '...'}, " ")' has an invalid token.
   at MS.Internal.Xml.XPath.XPathScanner.NextLex()
   at MS.Internal.Xml.XPath.XPathParser.ParseMethod(AstNode qyInput)
   at MS.Internal.Xml.XPath.XPathParser.ParsePrimaryExpr(AstNode qyInput)
   at MS.Internal.Xml.XPath.XPathParser.ParseFilterExpr(AstNode qyInput)
   at MS.Internal.Xml.XPath.XPathParser.ParsePathExpr(AstNode qyInput)
   at MS.Internal.Xml.XPath.XPathParser.ParseUnionExpr(AstNode qyInput)
   at MS.Internal.Xml.XPath.XPathParser.ParseUnaryExpr(AstNode qyInput)
   at MS.Internal.Xml.XPath.XPathParser.ParseMultiplicativeExpr(AstNode qyInput)
   at MS.Internal.Xml.XPath.XPathParser.ParseAdditiveExpr(AstNode qyInput)
   at MS.Internal.Xml.XPath.XPathParser.ParseRelationalExpr(AstNode qyInput)
   at MS.Internal.Xml.XPath.XPathParser.ParseEqualityExpr(AstNode qyInput)
   at MS.Internal.Xml.XPath.XPathParser.ParseAndExpr(AstNode qyInput)
   at MS.Internal.Xml.XPath.XPathParser.ParseOrExpr(AstNode qyInput)
   at MS.Internal.Xml.XPath.XPathParser.ParseXPathExpresion(String xpathExpresion)
   at System.Xml.XPath.XPathExpression.Compile(String xpath, IXmlNamespaceResolver nsResolver)
   at System.Xml.XPath.XPathNavigator.Evaluate(String xpath)
   at XPathCLI.Main(String[] args)

Let’s jump straight to the one that made it past Mono’s parser to crash in the evaluator:

>XPathCLI.exe "string-join(//something, \"separator\")"

Unhandled Exception: System.Xml.XPath.XPathException: Namespace Manager or XsltContext needed. This query has a prefix, variable, or user-defined function.
   at MS.Internal.Xml.XPath.CompiledXpathExpr.get_QueryTree()
   at System.Xml.XPath.XPathNavigator.Evaluate(XPathExpression expr, XPathNodeIterator context)
   at System.Xml.XPath.XPathNavigator.Evaluate(String xpath)
   at XPathCLI.Main(String[] args)

From this we can make a few conclusions:

  • Mono, MS.NET, and PHP do not support XPath 2.0. I cannot find any PHP documentation that claims a specific version of XPath support, but, as noted in the intro paragraph, MSDN claims XPath 2.0 support and MS.NET does not deliver. (Mono may be following the MS.NET implementation instead of the spec, so whether this is a Mono bug or not is debatable.)
  • Mono, MS.NET, and PHP do not support the {...} construct, which is present in the XPath 2.0 “Precedence Order” section but not actually defined elsewhere. This construct is not present at all in the XPath 1.0 specification. Whether this is a specification or implementation defect is left an open question.
  • Mono, MS.NET, and PHP do not implement the string-join function defined in at least XPath 2.0.

And from those conclusions we can draw a few more.

  • Nobody gives a whip about following the XPath specification.
  • The XPath specification is broken. Or confusing. Or (more likely) both.

The real question, then, is do people intentionally not implement the XPath 2.0 specification because they don’t want to, or because parts of it make no sense? It seems odd to me that an implementation would support concat and not string-join, especially since they are defined right next to each other.

In any case, if you’re not implementing all of it, don’t claim that you do. Incorrect documentation is worse than no documentation.