Hi. This is a trivial PHP library for parsing and utilizing XBEL documents. I wrote it to demonstrate principles of object-orientation to a friend. I believe it works and it seems fast enough to me.
As it happens, it also includes a nice SAX wrapper.
XBEL is a simple XML-based bookmark format. It stands for XML Bookmark Exchange Language. Do read more about it.
A short example might look like this:
<!DOCTYPE xbel PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML" "http://www.python.org/topics/xml/dtds/xbel-1.0.dtd"> <xbel version="1.0"> <title>Daniel's Bookmarks</title> <folder id="source-hosting"> <title>VCS Hosts</title> <bookmark href="http://bitbucket.org/"> <title>bitbucket</title> <desc>Definitely the best of the best.</desc> </bookmark> <separator/> <alias ref="github"/> <bookmark href="http://www.github.com/" id="github"> <title>Github</title> <desc>Blecch.</desc> </bookmark> </folder> </xbel>
I chose to do this project with XBEL because the document structure is not completely trivial; technically, it requires a push-down automata to parse because it has arbitrarily nested folders, handling
<alias/> tags requires forward-referencing, and it has several node types that have some or more in common. To parse XBEL is hard enough that you have to be structured in your approach, but easy enough that the structuring will mostly overwhelm the domain complexity, making it a good, functional way to show OO patterns and principles.
How do I use it?
lib/ directory into a folder you can get to it, and do this:
<?php require_once 'lib/XBEL.php'; $bookmarks = XBEL\Parser::parseXBEL("example-xbel.xml"); ?>
Consult the documentation for API information.
What's so interesting about your design?
Not much. Principally, I show how to make an OO wrapper around a procedural API in SAX\Parser, using PHP's procedural libxml-based SAX-like API. From there, I implement XBEL\Parser as a subclass, showing how one uses a more traditional OO SAX API.
The XBEL structure itself is rather OO, though I did take one shortcut (Alias and Separator are not Node subclasses). Basically, you treat Node as the parent class and you have a set of subclasses that refine it based on the type of thing you have in an XBEL document; principally Bookmark and Folder.
As a twist, I implement the Visitor pattern on this data structure in the form of XBELVisitor. PHP won't enforce the use of interfaces, so there's no real difference between having this interface or just using AbstractXBELVisitor, but I wanted to make it as explicit as possible.
For fun and because it was easy, XBEL\Parser uses XBELVisitor in its last parsing step to reify the
<alias/> nodes. Check it out in the source code for XBEL\Parser::endDocument().
This code is available under the Revised BSD license.