Total votes: 0
Print: Print Article
Please login to rate or to leave a comment.
Published: 24 Jul 2009
An overview of the Fizzler project.
CSS is one of the underlying components of the modern web, second only to HTML in forming the pages visited by millions on a daily basis. This prevalence has lead to a huge pool of knowledge about the subject, and in the core method of applying CSS rules – selectors. It's these selectors which the Fizzler project is interested in. The way in which a browser uses them to pick elements from a page is a technique which can be used in a large number of other applications. The Fizzler codebase is split into a couple of different projects; the core of Fizzler takes the latest CSS 3 Selector specification and wraps it up in a .NET library for consumption in a variety of ways.
The Fizzler.Systems projects then provide implementations for various types of document systems you can select against - for example Fizzler.Systems.HtmlAgilityPack parses HTML documents ready for Fizzler’s core to select against them. It also ships with a number of utility applications for viewing how Fizzler can interpret a document based on selectors which you provide.
Why CSS Selectors?
Out of the box, Fizzler can operate against HTML. Traditionally, developers might use XPath to pull parts of these documents through, or in some cases simply read through a document until they find the information they require. However there are a number of compelling reasons why CSS could be preferable to either of these solutions.
- Developer experience
In effect, developer experience could encompass simplicity and conciseness too, since a simple and concise notation is always going to make for happier developers. Take a look at this example XPath selector:
This isn't too complicated, but it is pretty long. The same thing as a CSS selector:
Better - less cruft, and more readable and would be easier to digest if combined with anything else. Again:
And as a CSS selector:
There's much less noise in the CSS selector version, which is likely to improve maintainability moving forward. While there will be certain scenarios in which XPath is the best choice, we can see that there are clear benefits to using CSS selectors in your code.
Let's take a look at some operations on the following XML fragment.
Fizzler’s default implementation for HTML documents is in the Fizzler.Systems.HtmlAgilityPack project, and works by providing extension methods for HtmlAgilityPack’s HtmlNode. Assuming we’ve loaded up our raw HTML up with HtmlAgilityPack and then used the variable “document” to contain the top-level document node, we can proceed to select some child elements:
This will pull all of the owner nodes from the document, regardless of which project they are in.
That will select all of the projects which have a name beginning with “F”. While in this example we’ve used well-formed XML, sloppy HTML will likely to be a very common sight for many developers. By combining the power of HtmlAgilityPack with Fizzler, we can remove the pain of parsing HTML and the pain of pulling out the relevant information. Here are some possible examples of how Fizzler can be used in the context of HTML web pages:
This will select all of the hyperlinks on the page which link to external websites.
We can use a selector like this to pull out the first items in every order list on the page - if we assume that those lists are ordered in terms of priority, and then we can pluck out the most important elements from each list for further processing.
The Fizzler Applications
The Fizzler code contains a couple of interesting extra applications – ConsoleFizzler and VisualFizzler – which enable developers to work with Fizzler without having to code it into their own applications. ConsoleFizzler is built as “fizz.exe” and can be used in two ways, with the first being a selection mode:
This will display a list of nodes within index.html which match the selector “.menuItem”. The second mode is explain:
This will output a description of the selector – a human readable form that explains which nodes will be pulled from the document. For example:
This can be extremely useful to help developers interpret more complex, chained selectors available in the CSS 3 specification.
Secondly, we have VisualFizzler, which allows a user to load a document up for selection. When a selector is provided, VisualFizzler will highlight the nodes in the document which will be selected, provide a list of the nodes, and output a human-readable explanation of what is being selected.
This application aids users and developers in diagnosing and interpreting how selectors can operate on specified documents. While the Fizzler library is designed for developers, both VisualFizzler and ConsoleFizzler may prove useful for a variety of end-users.
How It All Works
The guts of Fizzler, found in the main Fizzler project, are completely ignorant of the type of nodes which are being selected; the separate Systems handle that aspect. But Fizzler core does still host several key class implementations which enable this open architecture. Initially, Tokener and Parser implementations are used to break down the selector string which has been passed, and that information is then user to create a selector which is specific to a node tree.
ISelectorGenerator implementations do that kind of work; they also allow developers to provide their own node selector generators - Fizzler's defaults are mainly interested in XML and HTML node trees but there are many possibilities.
When developers do provide such implementations, their selections automatically take on deferred semantics, due to the way in which Fizzler uses IEnumerable and the yield keyword to create lazy sequences, only processing up to the required nodes in a collection and no further. For example, something such as
QuerySelectorAll("p").Take(2) could be used to pull only two elements from the yielded elements without needing to process any further than the second element.
Fizzler is currently at version 0.9, with a 1.0 release coming shortly. With wide support for .NET 2.0, 3.0, 3.5 and Mono, plus implementations for the majority of CSS selectors, Fizzler is already extremely capable, and the 0.9 designation is used to give the project API and implementation time to settle before releasing it to the world. There are also a number of CSS 3 selectors which are yet to be implemented and which are targeted to the 1.0 release. Fizzler is hosted on Google Code at fizzler.googlecode.com and is open to accepting patches for outstanding issues, especially the CSS selector implementations. The open architecture of Fizzler means that developers can extend it - perhaps by providing their own implementations of ISelectorGenerator. By doing so, developers can leverage Fizzler to query any kind of node tree - for example the Fizzler sandbox contains an implementation for Winforms, and Colin Eberhardt created one for WPF which he used to style XAML definitions. Fizzler's open nature means that anyone can jump on board and submit improvements and extensions for inclusion in the next public release.
Fizzler provides modern CSS selector support for .NET Framework developers working with .NET 2.0, 3.0 and 3.5, enabling the use of established CSS techniques within a variety of applications. Additionally, Fizzler provides a means of adding Systems to cater for custom requirements, bringing the selector paradigm to new and exciting areas. Fizzler also supports the Mono project, meaning the features it provides can be used in cross- platform applications. For developers working with HTML and XML documents, Fizzler not only provides out-of-the-box parsing via external libraries, but also a straightforward, easy to integrate API. ConsoleFizzler and VisualFizzler give diagnostic tools for both developers and end-users, and provide a quick-start means of exploring the power of the Fizzler library.
Please login to rate or to leave a comment.