<?xml version="1.0"?><results>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="137" id="137"><title>iTunes Playlist to Blog</title><description>
While messing around today I wrote a little Python script to post an iTunes playlist to a Metaweblog API enabled blog (like MovableType). I'm toying with the idea of using it to auto-post a top 25 list of songs once per week or something. The script is available <a href="http://www.xmldatabases.org/files/playlistToBlog.txt">here</a>.<p/>Here's what the top 25 looks like for this week. This is from an iTunes smart playlist that shows the top 25 most played songs that have been added to my library in the last month. iTunes smart playlists are an absolutely great feature that I hope shows up in other places in Mac OS X, like oh maybe in the Finder as a smart list of files. <p/><table><tr><th>Artist</th><th>Song</th><th>Album</th><th>Play Count</th></tr><tr><td>Metallica</td><td>Frantic</td><td>St. Anger</td><td>12</td></tr><tr><td>Massive Attack</td><td>Antistar</td><td>100th Window</td><td>11</td></tr><tr><td>Massive Attack</td><td>Butterfly Caught</td><td>100th Window</td><td>11</td></tr><tr><td>Massive Attack</td><td>Everywhen</td><td>100th Window</td><td>11</td></tr><tr><td>Massive Attack</td><td>Future Proof</td><td>100th Window</td><td>11</td></tr><tr><td>Massive Attack</td><td>Name Taken</td><td>100th Window</td><td>11</td></tr><tr><td>Massive Attack</td><td>Hymn Of The Big Wheel (Origin</td><td>Hymn Of The Big Wheel</td><td>11</td></tr><tr><td>Metallica</td><td>Dirty Window</td><td>St. Anger</td><td>11</td></tr><tr><td>Metallica</td><td>My World</td><td>St. Anger</td><td>11</td></tr><tr><td>Annie Lennox</td><td>A Thousand Beautiful Things</td><td>Bare</td><td>10</td></tr><tr><td>Annie Lennox</td><td>Bitter Pill</td><td>Bare</td><td>10</td></tr><tr><td>Annie Lennox</td><td>Erased</td><td>Bare</td><td>10</td></tr><tr><td>Evanescence</td><td>Bring Me To Life (Feat. Paul</td><td>Fallen</td><td>10</td></tr><tr><td>Massive Attack</td><td>Prayer For England</td><td>100th Window</td><td>10</td></tr><tr><td>Massive Attack</td><td>Small Time Shot Away</td><td>100th Window</td><td>10</td></tr><tr><td>Massive Attack</td><td>Special Cases</td><td>100th Window</td><td>10</td></tr><tr><td>Massive Attack</td><td>What Your Soul Sings</td><td>100th Window</td><td>10</td></tr><tr><td>Massive Attack</td><td>Any Love (Larry Heard Mix)</td><td>Hymn Of The Big Wheel</td><td>10</td></tr><tr><td>Massive Attack</td><td>Home Of The Whale</td><td>Hymn Of The Big Wheel</td><td>10</td></tr><tr><td>Massive Attack</td><td>Hymn Of The Big Wheel (Nellee</td><td>Hymn Of The Big Wheel</td><td>10</td></tr><tr><td>Annie Lennox</td><td>Honestly</td><td>Bare</td><td>9</td></tr><tr><td>Annie Lennox</td><td>Loneliness</td><td>Bare</td><td>9</td></tr><tr><td>Annie Lennox</td><td>Oh God (Prayer)</td><td>Bare</td><td>9</td></tr><tr><td>Evanescence</td><td>Everybody`s Fool</td><td>Fallen</td><td>9</td></tr><tr><td>Evanescence</td><td>Going Under</td><td>Fallen</td><td>9</td></tr></table><p/>What's funny is that I have a tremendous breadth of musical interest, but you sure wouldn't know it from this list. I bought a number of more popular albums a couple weeks ago which skews the results away from the more eclectic mix I usually get from <a href="http://www.emusic.com">eMusic</a>. <p/>Currently Playing "Marquis Cha-Cha" by "The Fall" from the album "Palace Of Swords Reversed", a little more eclectic bit from eMusic.<p/></description><category>Mac OS X</category><category>Music</category><category>Programming</category><category>Python</category><category>Web Services</category><pubDate seconds="1056931275.0">2003-06-29T17:01:15-07:00</pubDate><comment-count>1</comment-count><trackback-count>0</trackback-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="162" id="162"><title>PyObjC 1.0b1 Released</title><description>
The improvements include:  Improved performance and stability, Better tutorials and examples, Initial support for MacOS X 10.1, Support for the WebKit framework, Write plugin bundles in Python (requires Python 2.3) [<a href="http://www.blankreb.com/studiolog.php">Studio Log</a>]<p/>I've been playing around with the 0.9 release of PyObjC. It's a very promising project badly in need of better documentation. I've really been getting into Python lately and have been using it heavily with my Cocoa projects. I'd love to see Python included by Apple as a full peer with Objective C and Java for Cocoa applications. It would make Cocoa development even easier then it already it. Applescript Studio is nice, but Applescript is still not a language that I feel comfortable with and the way it is integrated with Cocoa means there are quite a few things you can't do with Applescript. I've found it easier to just stick with Objective C. The way PyObjC is being integrated it is functionally equivalent to Objective C and should bring all the power along with the ease of a scripting language.
</description><category>Mac OS X</category><category>Programming</category><category>Python</category><pubDate seconds="1057778293.0">2003-07-09T12:18:13-07:00</pubDate><trackback-count>0</trackback-count><comment-count>0</comment-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="191" id="191"><title>Python 2.3 released</title><description>
<div class="excerpt">July 29, 2003<br/>
Press Release<br/>
SOURCE: Python Software Foundation<B>PYTHON SOFTWARE FOUNDATION (PSF) ANNOUNCES PYTHON VERSION 2.3</B><br/><I>New release enhances powerful programming language</I><I>FREDERICKSBURG, Va., July 29, 2003</I> -- The <a HREF="http://www.python.org/psf">Python Software Foundation</a> (PSF)
announces the release of version 2.3 of the <a HREF="http://www.python.org/">Python programming language</a>. This
major release introduces performance enhancements, increased
robustness, several minor language features, many additions to the
extensive standard library, improved support for Mac OS X and several
other Unix-based systems, and a large number of other improvements.</div><p/>... and if the release of Python 2.3 w/first class OS X support were not enough ....<p/><div class="excerpt">"The combination of the open source Unix-based core of Mac OS X running on PowerBook G4 high-performance portables has attracted a large number of developers using open source scripting languages like Python," said Bud Tribble, Apple's vice president of Software Technology. "Python 2.3 provides greatly improved support for existing Mac OS X users, and with the upcoming release of Panther, Apple will provide Python 2.3 developers direct access to APIs for the PDF-based Quartz graphics engine and QuickTime image formats."</div><p/>Excellent.   And, of course, <a href="http://pyobjc.sourceforge.net">PyObjC</a> will continue to provide first class support for integrating Python and Objective-C, including full blown Cocoa application development using Python in place of Objective-C.<p/>... and on my son's third birthday and everything. [<a href="http://www.pycs.net/bbum/">bbum's rants, code &amp; references</a>]
</description><category>Mac OS X</category><category>Python</category><pubDate seconds="1059547406.0">2003-07-29T23:43:26-07:00</pubDate><trackback-count>0</trackback-count><comment-count>0</comment-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="215" id="215"><title>XML Document Construction With Python and libxml2</title><description>
The <a href="http://xmlsoft.org/">libxml</a> <a href="http://xmlsoft.org/python.html">Python API</a> is very lightly documented, so this is an attempt to fill in some of the holes that exist.<p/>

	<h3>Creating a new document</h3>
 


<p/>To create a new document using the libxml2 API you use a document constructor function that returns an empty document instance. This method takes one argument that repesents the XML version of the document being created. 
 
<pre>
 import libxml2
 doc = libxml2.newDoc("1.0")
</pre><p/>	<h3>Creating elements</h3>
 
<p/>Once you have a document instance you then need to add elements to it. First off you need to create the root element.<p/><pre>
root = doc.newChild(None, "root-element", None)
</pre>
<p/>The root node is created using the <code>xmlDoc.newChild()</code> method. This method takes three parameters.<p/>
<ul>
	<li>namespace - The namespace that the element should belong to or <code>None</code> if no namespace.</li>
	<li>node name - The name of the node with no namespace prefix.</li>
	<li>element content - The content for the element or <code>None</code> if the element is empty.<p/>In this particular case we're creating an empty element named <code>root-element</code>. If we were to print this out at this point it would look something like this.</li>
</ul>
 
<p/><pre>
&lt;?xml version="1.0"?&gt;
&lt;root-element/&gt;&lt;p /&gt;</pre><p/>If we wanted to put the node into a namespace we would write this instead.<p/><pre>
root = doc.newChild(None, "root-element", None)
namespace = root.newNs("http://example.com/sample", "sample")
root.setNs(namespace)
</pre><p/>The resulting document then becomes.<p/><pre>
&lt;?xml version="1.0"?&gt;
&lt;sample:root-element xmlns:sample="http://example.com/sample"/&gt;&lt;p /&gt;</pre><p/>Now that we've created the root we can continue adding elements to the document. We can add a element <code>child-node</code> in the <code>http://example.com/sample</code> namespace by adding.<p/>
<pre>
child = root.newChild(namespace, "child-node", None)
</pre><p/>And our document now looks like <p/><pre>
&lt;?xml version="1.0"?&gt;
&lt;sample:root-element xmlns:sample="http://example.com/sample"&gt;
    &lt;sample:child-node/&gt;
&lt;/sample:root-element&gt;

</pre><p/>If we had wanted to included some text within the added child it's as simple as just changing the third parameter to newChild.<p/>

<pre>
child = root.newChild(namespace, "child-node", "Some sample text")
</pre><p/>Which generates the document<p/>

<pre>
&lt;?xml version="1.0"?&gt;
&lt;sample:root-element xmlns:sample="http://example.com/sample"&gt;
    &lt;sample:child-node&gt;Some sample text&lt;/sample:child-node&gt;
&lt;/sample:root-element&gt;&lt;p /&gt;</pre><p/>Adding an attribute to an element is also very easy. <p/><pre>
child = root.newChild(namespace, "child-node", "Some sample text")
child.setProp("an-attribute", "with a value")
</pre><p/>Which of course generates a document that looks like this.<p/><pre>
&lt;?xml version="1.0"?&gt;
&lt;sample:root-element xmlns:sample="http://example.com/sample"&gt;
    &lt;sample:child-node an-attribute="with a value"&gt;Some sample text&lt;/sample:child-node&gt;
&lt;/sample:root-element&gt;&lt;p /&gt;</pre><p/>If you wanted the attribute to be part of a namespace, you use setNsProp instead of setProp.<p/><pre>
child = root.newChild(namespace, "child-node", "Some sample text")
child.setNsProp(namespace, "an-attribute", "with a value")
</pre><p/>And the result<p/><pre>
&lt;?xml version="1.0"?&gt;
&lt;sample:root-element xmlns:sample="http://example.com/sample"&gt;
    &lt;sample:child-node sample:an-attribute="with a value"&gt;Some sample text&lt;/sample:child-node&gt;
&lt;/sample:root-element&gt;&lt;p /&gt;</pre><p/>Beside simple elements and attributes libxml defines methods to create all the other common XML types. Here's a summary of the methods that are available. <p/>


<ul>
	<li><code>xmlDoc.newDocComment(comment)</code> - Creates a comment node.</li>
	<li><code>xmlDoc.newCDataBlock(content, length)</code> - Create a CDATA section.</li>
	<li><code>xmlDoc.newDocText(content)</code> - Creates a new text node.</li>
</ul>

<p/>These methods are all node construction methods that are called to create the instance of the required type. Once you have the instance you then need to add it into the document tree where ever you want it. There's also a function available to create processing instructions. This function differs in that it called on the libxml2 module, rather then an xmlDoc instance.<p/>

<ul>
	<li><code>libxml2.newPI (name, content)</code> - Creates a processing instruction</li>
</ul>

<p/>Since these functions require you to create the node and then  add it to the document in two steps, libxml provides a number of methods to control where the node is placed in the document tree. These methods are available on any instance of an <code>xmlNode</code>. <p/>

<ul>
	<li><code>xmlNode.addChild(node)</code> - Appends the new node to the list of children for the node.</li>
	<li><code>xmlNode.addChildList(nodeList)</code> - Appends a list of new nodes to the children for the node.</li>
	<li><code>xmlNode.addNextSibling(node)</code> - Adds the new node as a sibling after the selected node.</li>
	<li><code>xmlNode.addPrevSibling(node)</code> - Adds the new node as a sibling before the selected node.</li>
	<li><code>xmlNode.addSibling(node)</code> - Adds the new node as a sibling after the selected node. (similar to addNextSibling)</li>
	<li><code>xmlNode.addContent(content)</code> - Appends additional text content to an element.<p/>Here's an example that puts everything together.</li>
</ul>
 
<p/><pre>
#!/usr/local/bin/python 
import libxml2
doc = libxml2.newDoc("1.0")

root = doc.newChild(None, "root-element", None)
namespace = root.newNs("http://example.com/sample", "sample")
root.setNs(namespace)

child = root.newChild(namespace, "child-node", "Some sample text")

child.setNsProp(namespace, "an-attribute", "with a value")

comment = doc.newDocComment("Just commenting")
child.addPrevSibling(comment)

pi = libxml2.newPI("a-sample-pi", "with some useless content")
root.addPrevSibling(pi)

text = doc.newDocText(" This will be added to the existing text.")
child.addChild(text)

child.addContent(" This will also be added to the text")

print doc.serialize(None,  1)

</pre>

<p/>And a final result.<p/>

<pre>
&lt;?xml version="1.0"?&gt;
&lt;?a-sample-pi with some useless content?&gt;
&lt;sample:root-element xmlns:sample="http://example.com/sample"&gt;
&lt;!--Just commenting--&gt;
  &lt;sample:child-node sample:an-attribute="with a value"&gt;Some sample text This will be added to the existing text. This will also be added to the text&lt;/sample:child-node&gt;
&lt;/sample:root-element&gt;

</pre><p/></description><category>Programming</category><category>Python</category><category>XML</category><category>XML Databases</category><pubDate seconds="1060483358.0">2003-08-09T19:42:38-07:00</pubDate><comment-count>1</comment-count><trackback-count>0</trackback-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="216" id="216"><title>Installing Berkeley DB XML on Mac OS X with Python and Perl API support</title><description>
I just wanted to post some notes about installing <a href="http://www.sleepycat.com/products/xml.shtml">Sleepycat Berkeley DB XML</a> on Mac OS X 10.2 with Perl and Python support. The builds are relatively straight forward and Sleepycat has posted a <a href="http://www.merrells.com/john/dbxml/archives/cat_faq.html#000173">simple script</a> to help build Berkeley DB XML it self. However, it isn't clear what is necessary to get Perl and Python working. <p/>

The most important thing, before you start compiling anything, make sure you have the latest GCC 3.3 from Apple. This is distributed as a patch to the December 2002 developer tools. This is critical, without it Python and Perl support will not work. <p/>

Next, unfortunately, you'll have to build a new Perl and Python. The Mac OS X 10.2 Python should be the right version, but I couldn't get it to work. Building a fresh Python 2.3 does work. For Perl, Mac OS X includes Perl 5.6 and Berkeley DB XML requires 5.6.1 so you have to build a new one. I used Perl 5.8.0 and it seems to work fine. So you have to build a new Python, a new Perl and the Berkeley DB XML distribution. These should all build using the standard instructions and for DB XML you can use their <a href="http://www.merrells.com/john/dbxml/archives/cat_faq.html#000173">script</a>.<p/>

Once you have all that built, you can then build the DB XML Perl and Python libraries. <p/>For Python you first need to build and install <a href="http://pybsddb.sourceforge.net/">bsddb3</a>, once that's done you can build the python support for DB XML in the usual Python fashion. Make sure the python you're using is the one you built previously. Unless you specified otherwise, it's installed in /usr/local/bin/python.<p/>

cd dbxml-1.1.0/src/python<br/>
/usr/local/bin/python setup.py build<br/>
sudo /usr/local/bin/python setup.py install
<p/>

There's an example Python program in dbxml-1.1.0/examples/python/examples.py that you can run to test the build.<p/>For Perl you just build it in the usual Perl manner. Again, make sure you use the perl you compiled.<p/>
cd dbxml-1.1.0/src/perl<br/>
/usr/local/bin/perl Makefile.PL <br/>
make <br/>
sudo make install<p/>
There are some examples for the Perl API in dbxml-1.1.0/src/perl/examples.<p/></description><category>Mac OS X</category><category>Programming</category><category>Python</category><category>XML</category><category>XML Databases</category><pubDate seconds="1060486380.0">2003-08-09T20:33:00-07:00</pubDate><comment-count>1</comment-count><trackback-count>0</trackback-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="219" id="219"><title>Thinking about Blosxom</title><description>
I'm thinking about moving this site to <a href="http://www.blosxom.com">Blosxom</a> from <a href="http://www.movabletype.org">MovableType</a>. I'm getting annoyed with a lot of things about MovableType, in particular how slow it is when publishing. Each time I add a post it gets a little slower and it's starting to really bug me. I'm also annoyed by how cumbersome it is to edit templates, especially since I have more then one blog and they all use the same templates. I also like the way NetNewsWire handles Blosxom blogs, it shows you the hierarchy and all posts you've made at all times. With MovableType you only get your recent posts and if you restart NetNewsWire you'll only get the last 10 or so posts you've made. This makes it really cumbersome to go back and edit your old posts. There are many other little things as well that are bugging me as I use this system more.<p/>I really like the simple, simple file based mechanism that Blosxom uses. I've always considered MovableType's use of a database as massive overkill (even if it is just MySQL). I also like the idea of being able to build the whole thing locally and then just shove it up on the server with nothing major needing to be installed on the server. <p/>After reading through the documentation it looks like the one problem area with Blosxom may be categories. I tend to add posts into several different categories, but it looks like Blosxom may only support one category for each post. I'll explore this a little more to find out for sure, but it can't be that hard to make it use symlinks or something to do it.<p/>I found this <a href="http://revjim.net/item/9539/">site</a> which has some pretty good information on making the move.<p/>There's also a version <a href="http://roughingit.subtlehints.net/pyblosxom">written in Python</a> that looks interesting. Hmm, that could actually be fun. Blosxom is written in Perl and even though I'm perfectly comfortable writing Perl code, it's not something I really enjoy anymore. Python, however I do like. Very, very tempting.<p/>If I do make this move it will be the fourth time I've changed the software I use for this blog. Ugh! Sadly, it probably won't be the last either.
</description><category>Python</category><pubDate seconds="1060506273.0">2003-08-10T02:04:33-07:00</pubDate><trackback-count>0</trackback-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="226" id="226"><title>10 Python Pitfalls</title><description>
A good list of <a href="http://zephyrfalcon.org/labs/python_pitfalls.html">common problems</a> in Python. I like Python, but I'm anything but an expert so I learned a thing or two from this.
</description><category>Python</category><pubDate seconds="1060880410.0">2003-08-14T10:00:10-07:00</pubDate><trackback-count>0</trackback-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="233" id="233"><title>Still thinking about Blosxom</title><description>
I'm still <a href="http://www.xmldatabases.org/movabletype/archives/000270.html">thinking about</a> converting this site to running on a Blosxom derivative, in particular on <a href="http://roughingit.subtlehints.net/pyblosxom/">Pyblosxom</a>. I spent a fair amount of time over the last week getting everything working in a test setup and I've worked everything out, except I'm worried about the performance of it. Even running on my dual 1.25Ghz Powermac there's a noticeable delay when viewing a page. This concerns me as the server this site runs on is only a dual 266Mhz Pentium II. I haven't tested it on this machine yet. This really shouldn't be a major problem as this site doesn't get all that much traffic and the network is kind of slow anyway, but CGI scripts always bug me. This is the one good thing about MovableType, it's slow to post, but that's because it creates static pages for everything.<p/>The Perl version of <a href="http://www.blosxom.com">Blosxom</a> can also be used to generate static pages, the Python version can't.<p/>So far I've written four plugins for Pybosxom to make it as compatible with the current site as possible. I had to add <a href="http://www.purl.org/rss/1.0/">RSS 1.0</a> support, <a href="http://textism.com/tools/textile/">Textile</a> formatting support and a post body summarize function. Along with these I also created a new plugin that tracks referrers and hit counts on a per post basis. That one was more my experimenting with <a href="http://www.merrells.com/john/dbxml/">Berkeley DB XML</a> then anything, but it's very useful.<p/>Anyway, now I'm stuck trying to decide whether to go with Pyblosxom, go with the original Perl Blosxom or to punt on the whole thing and just stick with MovableType.
</description><category>Mac OS X</category><category>Python</category><category>Web Services</category><category>XML Databases</category><pubDate seconds="1061269903.0">2003-08-18T22:11:43-07:00</pubDate><trackback-count>0</trackback-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="234" id="234"><title>Java Programmers Unite: Say NO To Python</title><description>
In his comparison of Java and Python productivity, Steve Ferg notes that: A programmer can be significantly more productive in... Via: <a href="http://www.cardboard.nu/archives/000118.html">Nu Cardboard</a><p/>This is kind of funny, but I do agree with the assessment that Python is vastly more productive then Java. I spent several years working with Java and in retrospect it was astonishingly unproductive. This included a project where I converted a team development effort from Perl to Java for all the reasons that are commonly stated for making such moves. In retrospect that was a horrible decision. I did it under the belief that we would have a more scalable process, more stable code and ultimately faster development of new applications because of this. It never really worked out that way and this was with Perl. I really regret making that move even though Perl is a far worse language for team projects then Python is. Over the last few months I've been working more and more with Python and I'm pretty convinced that the difference in raw productivity makes up for any loss from static typing and a compilation phase. I believe the same applies to Perl, although not quite as much.<p/>What's important to understand about running scripting languages in large projects is you have to have good tests. When we were using Perl we had lots of unit tests, however when we switched to Java the code itself took too much precedence and the creation of unit tests suffered. Sure it's nice to have a testing policy, but schedule pressure can have nasty ways of interfering, especially when the overhead of the language is slowing things down. In the end our system became even harder to change then when we started out. The problem of course is that just because a language is statically typed and compiled it does not remove the need to write tests. So you're now taking on the burden of a less productive language while not shedding the burden of writing comprehensive tests. In addition, because of the static typing, compilation phase and OO access protection features of languages like Java your tests have also become much harder to write.<p/>Because of this, I'm really starting to believe that efforts to improve software quality by tightening up the language features through stronger typing and rigid language features are really the wrong approach. I tend to believe a more profitable future will be attained by making languages easier to use and building in mechanisms that improve the testability of code. My feeling is that it isn't really important that you pass the right type to the right method, what's important is that the code does what it is supposed to do. Passing the right type to the right method may be a precondition for this, however it is not sufficient to guarantee it, and that to me just makes it overhead. Tests are still required. If dealing with all the static typing and compilation phases makes test development suffer, then I tend to believe those features are counterproductive and just get in the way. 
</description><category>Programming</category><category>Python</category><pubDate seconds="1061315219.0">2003-08-19T10:46:59-07:00</pubDate><trackback-count>0</trackback-count><comment-count>0</comment-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="238" id="238"><title>libxml2 2.5.10 and libxslt 1.0.32 released</title><description>
Daniel Veillard has released new versions of libxml2 and libxslt, classifying the libxml2 release as a "major bugfix release", and writing that libxml2 2.5.9 and 2.5.10 "include a lot of bugfixes spanning the whole library; upgrading is strongly recommended." The libxslt 1.0.32 release is also significant in that it is the first to include Python bindings for extension elements. [<a href="http://www.xmlhack.com">xmlhack</a>]<p/>I've been using libxml2 in Python a lot lately. It's the first XML parser I actually like, mainly because of the very convenient XPath API. 
</description><category>Python</category><category>XML</category><pubDate seconds="1061492020.0">2003-08-21T11:53:40-07:00</pubDate><trackback-count>0</trackback-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="240" id="240"><title>libxslt Extension Functions in Python</title><description>
This is just a note about writing extension functions for libxslt. The documentation on this is slim at best and the only example that comes with libxslt is minimal. <p/>I'm working on a project where I wanted to run a piece of text through a <a href="http://textism.com/tools/textile/">textile</a> processor and then insert the result into the result tree of the XSL document. I thought this would be pretty simple, but it turned out to be a bit more work then I expected. Here's the code that finally works.<p/>Update: the original version of this code inserted the output directly into the tree. That's probably not what you want to really do, so I updated it to return the content.<p/><pre>
def textile_process(ctx, content):
    """
    An XSL-T extension function to process textile formatting included in a post.
    """
    try:
        node = libxml2.xmlNode(_obj=content[0])
        parserContext = libxslt.xpathParserContext(_obj=ctx)
        xpathContext = parserContext.context()
        
        resultContext = xpathContext.transformContext()
        source = "&lt;div&gt;" + textile.textile(node.content) + "&lt;/div&gt;"
        
        doc = libxml2.parseDoc(source)
        
        root = doc.getRootElement()
        root.unlinkNode()
        
 	# If you do this you insert the result directly into the output tree
        # resultContext.insertNode().addChild(root)	return [root]
    except Exception, err:
        sys.stderr.write("Context error " + str(err))
        
    return ""</pre><p/>The tricky parts about this code are converting all parameters into the right types and getting to the pieces of the documents that you need. The problem is that the parameters come in as raw <code>PyCObject</code> instances so you have to convert to the more specific object types manually. <p/>For the way I was using this function the content parameter contains a list with one item and that item is an <code>xmlNode</code>. So the code.<p/><pre>
node = libxml2.xmlNode(_obj=content[0])
</pre><p/>converts the <code>PyCObject</code> into an <code>xmlNode</code> instance that you can then use as you usually would. You have to do similar things with the <code>xpathParserContext</code> that comes in as the first parameter. From the <code>xpathParserContext</code> you then have to get an <code>xpathContext</code> and from that you get the context for the result document. The <code>xpathContext</code> variable provides a reference into the source document and the <code>resultContext</code> variable provides access to the document being created.<p/>Update: this paragraph applies to the commented out version of the original code. One confusing thing about the <code>resultContext</code> is the use of the <code>insertNode() </code>method. At first I thought that was inserting a new node into the result document, what it really is doing is requesting the node under which the result of the function will be inserted. It would probably have been clearer if the method was named <code>getInsertionNode()</code> or something like that.<p/>Now that this is working it's pretty slick, but it sure took a while to figure out exactly what needed to happen.
</description><category>Python</category><category>XML</category><pubDate seconds="1061724230.0">2003-08-24T04:23:50-07:00</pubDate></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="249" id="249"><title>Java on Mac OS X</title><description>
I mentioned in my <a href="http://www.xmldatabases.org/movabletype/archives/000280.html">rant</a> about window proliferation on Mac OS X that I was looking at using JEdit as a solution. It turns out <a href="http://www.jedit.org">JEdit</a> is almost a perfectly workable solution, through various plugins I was able to get it to do everything that I wanted and it felt close enough to a native app to not drive me crazy. Unfortunately, all is not well in this world. <p/>The JDK on Mac OS X has some serious problems when running JEdit. With the 1.4 JDK the VM crashes far too often. This shouldn't be JEdit's fault as it's the VM that's crashing. Unless jEdit is running some native code a Java app should never be able to crash the VM. This wouldn't have been a huge deal as JEdit is really good about saving its current state, just restarting the app is a minor annoyance. However, the real problem is that sometimes when the VM crashes it takes the whole WindowServer process down with it. This results in instant termination of all your running apps and getting logged out of the system. To say that's a bit of a problem is an understatement. <p/>When you install jEdit it recommends that you use the 1.3 VM. Unfortunately doing this also results in the loss of a number of functions (in particular mouse scroll wheel support) and substantially changes the display of the app (i.e. tab layouts). Also if you turn on the hardware acceleration it has problems with garbled text and incorrect positioning in text areas. Running without mouse scroll wheel support is extremely annoying. <p/>I'm quite disappointed with the current situation of Java on Mac OS X for running GUI apps. I've had no problems with it running server apps, it seems most of the current problems can be traced to the things they're doing with Swing, i.e hardware acceleration and the switch to the Cocoa toolkit for GUIs in 1.4. This stuff will be great once it's fully stable, but I've heard nothing about progress in this area for some time. <p/>I'm still trying to make do with jEdit running on the 1.3 VM with no hardware acceleration. However, I would definitely prefer to be able to take advantage of the 1.4 features, that scroll wheel thing can really spoil you.
</description><category>Mac OS X</category><category>Programming</category><category>Python</category><pubDate seconds="1062050889.0">2003-08-27T23:08:09-07:00</pubDate><comment-count>2</comment-count><trackback-count>0</trackback-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="323" id="553"><title>Drawbot</title><description><p>
Today, <a href=" http://just.letterror.com/~just/">Just van Rossum</a> released <a href="http://just.letterror.com/cgi-bin/wypy?DrawBot">Drawbot</a>. Drawbot is significant in a couple ways. Firstly because it's the first real application I've seen that was written in Python using <a href="http://pyobjc.sourceforge.net/">PyObjC</a>. This means it's a Cocoa application, but wasn't written in one of the usual Cocoa languages (i.e. Objective C, Java, Applescript). Secondly because it's an interesting tool that allows you to play with the Cocoa 2D drawing API from within a scripting environment. It provides its own simple graphics API, but it's also possible to use the Cocoa APIs directly. This makes it a good way to explore and play with the Cocoa drawing APIs from within Python. Pretty cool.
</p>

<div id="source">Source: <a href="http://www.pycs.net/bbum/">bbum's rants, code &amp; references</a></div>
</description><category>Mac OS X</category><category>Python</category><pubDate seconds="1065009877.06">2003-10-01T05:04:37-07:00</pubDate><comment-count>0</comment-count><trackback-count>0</trackback-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="377" id="606"><title>Webware performance</title><description><p>
I was recently asked in an email my thoughts about <a href="http://webware.sourceforge.net/">Webware's</a> performance. Figured I'd share them here as well. 

</p>
<p>
So far I've been entirely satisfied with the performance and stability of Webware. Running on my dual 1.25Ghz G4 desktop it serves data out of Syncato's cache at roughly 45% of static HTML speed. That's really not too bad given it's a dynamic request and is traversing a socket from Apache. It serves roughly 110 requests per second which is a 9.5 million requests per day pace. My production server is considerably slower since it's about 6 years old, but Webware is anything but the bottleneck in the system.

</p>
<p>
The one potential problem with Webware is really a problem with Python in general and that's the global interpreter lock in the Python interpreter. That will serialize certain operations that could be more efficient if run in parallel, especially when you have multiple CPUs. This would maybe be a problem if you were to actually try to push 9.5 million requests on a single machine. Fortunately 99.9% of sites don't get anywhere near that and if you do you should definitely have more then one machine anyway. My modest little site doesn't even begin to tap into that.
</p></description><category>Syncato</category><category>Web Services</category><category>Python</category><pubDate seconds="1066272278.63">2003-10-15T19:44:38-07:00</pubDate><comment-count>3</comment-count><trackback-count>0</trackback-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="378" id="607"><title>Givin libxml2 some love</title><pubDate seconds="1066273447.42">2003-10-15T20:04:07-07:00</pubDate><description><p>
I started working with <a href="http://xmlsoft.org/">libxml2</a> a few months ago and I've really grown to love it. After spending several years working with Java APIs like SAX and DOM, I'm absolutely thrilled with the simplicity of the libxml Python API. Yeah it's not standard, but who cares. I could never remember how to write SAX or DOM code anyway. No matter how much I used it I always had to open a book, with libxml it's just so much more natural. The libxml API still has all kinds of problems, but it's by far the most productive XML API I've ever used. 

</p>
<p>
My favorite feature by far, absolutely no question, the brain dead simple XPath API. 

</p>
<pre><![CDATA[
import libxml2
doc = libxml2.parseFile("something.xml")
results = doc.xpathEval("/some/path")

for result in results:
	# do something cool here
]]></pre>
<p>
A few lines of code, whole worlds of power. To me XPath is the swiss army knife of XML tools. Of course you'd never guess that if you were to look at the source code for <a href="http://www.syncato.org">Syncato</a>.

</p>

</description><category>XML</category><category>Python</category><comment-count>7</comment-count><trackback-count>0</trackback-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="389" id="618"><title>PyObjC 1.0</title><description><p>
<a href="http://pyobjc.sourceforge.net/">PyObjC 1.0 released</a><br/>PyObjC allows developers to write Cocoa apps in Python. [<a href="http://ranchero.com/">ranchero.com</a>]

</p>
<p>
I keep hoping to have more time to play with this. Objective C is already pretty easy, Python is even easier.

</p>

</description><category>Mac OS X</category><category>Python</category><pubDate seconds="1066611156.94">2003-10-19T17:52:36-07:00</pubDate><comment-count>0</comment-count><trackback-count>0</trackback-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="399" id="628"><title>libxml and XPath love is spreading</title><pubDate seconds="1066806437.25">2003-10-22T00:07:17-07:00</pubDate><description><p>
If nothing else comes out of my work on <a href="http://www.syncato.org">Syncato</a> it does seem to be raising the visibility of XPath as a general XML processing tool. First it was Sam Ruby attaining <a href="http://www.intertwingly.net/blog/1599.html">enlightenment</a>, now Simon Willison has had his own <a href="http://simon.incutio.com/archive/2003/10/21/xpathRocks">"enlightening experience"</a> after reading my post about <a href="http://www.xmldatabases.org/WK/blog/607?t=item">libxml love</a>.

</p>
<p>
Syncato takes XPath to the extreme and uses it for all XML manipulation, not just the queries through the URL. The next version of Syncato will also add a Python XPath document creation and modification API called PathUpdate. This allows you to create and modify documents by just providing paths to the nodes you want to create or modify. You can specify a deep path and it will create the whole hierarchy. Here's a sample from my unit tests that gives a flavor of how it works, it's pretty cool and very powerful. 

</p>

<pre><![CDATA[
# create a tree and then set a node to a new value
doc = PathUpdate()
doc.addNode("/root/child")
doc.updateNode("/root/child", "text")

self.assertEqual(doc.serialize(), '<?xml version="1.0"?>\n<root><child>text</child></root>\n')

# add another child and then update both to the same value
doc.addNode("/root/child")
doc.updateNode("/root/child", "newText")

self.assertEqual(doc.serialize(), '<?xml version="1.0"?>\n<root><child>newText</child><child>newText</child></root>\n')

# Now just update the second child.
doc.updateNode("/root/child[2]", "text")

self.assertEqual(doc.serialize(), '<?xml version="1.0"?>\n<root><child>newText</child><child>text</child></root>\n')

# Now update an attribute
doc.addNode("/root/child[1]/@attr", "text")
doc.updateNode("/root/child[1]/@attr", "newText")
self.assertEqual(doc.serialize(), '<?xml version="1.0"?>\n<root><child attr="newText">newText</child><child>text</child></root>\n')
 
]]></pre>
</description><category>XML</category><category>Syncato</category><category>Python</category><comment-count>0</comment-count><trackback-count>0</trackback-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="400" id="629"><title>Berkeley DB XML License</title><description><p>
I've been meaning to point to this for a while, but kept forgetting. Don Park has been <a href="http://www.docuverse.com/blog/donpark/2003/10/11.html#a970">talking</a> with Sleepycat about commercial use licenses for Berkeley DB XML. The way they define distribution is a little weird so it's worth reading what Don has to say about it. They're also being somewhat generous with licensing right now while the product is new.

</p>
</description><category>XML</category><category>XML Databases</category><category>Python</category><pubDate seconds="1066808549.79">2003-10-22T00:42:29-07:00</pubDate><comment-count>0</comment-count><trackback-count>0</trackback-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="401" id="630"><title>Programmers Block</title><description><p>
Does anyone else ever get this or is it just me? What I'm talking about is a deep mental block
that destroys productivity. Your mind is full of ideas, but when you sit down to try to realize them you get nowhere and your mind just starts to wander. 

</p>
<p>
I have this problem in a big way, I sometimes go for days or even weeks at a time where I can do absolutely nothing productive with the computer. Over the  last few months I've been trying to battle this and to figure out how to control it so that I can be happier with myself. So far I've had very limited success and it's a very frustrating experience. 
</p>
<p>
First you sit down and try to do something but for some reason it just doesn't feel right, so you go and do something else and that doesn't feel right, and on and on. What's the worst is when you start to get mad at yourself for not being productive. At that point you're just lost, I often tend to completely crash then and end up sleeping 18 hours straight or something. That's a huge waste of time and you wake up feeling like utter crap which makes it even harder to get your mind back in gear. It's like a deep downward spiral that is seemingly impossible to pull yourself out of.

</p>

<p>
I call it programmers block because I recently read a couple books on writers block. I figured it's a similar activity and the symptoms may also be similar. It turns out they are exactly the same and reading those books has been the one thing that has helped with the situation. 

</p>
<p>
I think my biggest problem is that I have big ideas. I constantly get these grand visions for some great new technology or piece of software or service or what ever and my adrenaline really gets pumping. I sit down, sketch it out and then start thinking about how great it's going to be when it's done. Boom, crash, there's the mistake. It's that vision of greatness that's a killer. Why? Because your mind gets about 100 steps ahead of reality and then when you sit down to try to turn it into a working system the mountain you've built seems too large to climb. Basically it's day-dreaming and dreams are often far removed from reality. This is something the books on writers block made very clear, the number one enemy of writers around the world is self doubt. That mountain of an idea that you have, even if you can envision how great it will be when it works, looks 100 times larger when you actually have to put all the pieces together to make it work. You look at that and reality sets in, and at least for me, I have a bad habit of crashing into a complete state of no productivity. I get frustrated with my inability to make progress then start to doubt my ability to do anything at all, and the situation just becomes ugly. 

 </p>
<p>
So how do you combat this? I really don't know for sure, but I do know it helps to think small. It especially helps to avoid the dangerous day-dreaming of greatness. I'm trying to consciously watch for this and kick myself every time I find myself thinking about how great something will be without actually working on it. My success has still been limited however. For instance I just came off a four day crash over the weekend. I did manage to dig myself out of it by forcing myself to just tackle a tiny little piece of a project, then the next little piece and so on. With this I was finally able to put together some good productive hours. Unfortunately it's hard, I tried and failed to do the same thing several times during the weekend. It doesn't help the situation any that I"m still battling pain in my wrists which tends to make me want to stay away from the computer too. 
</p>
<p>
I know that other people have this problem. How do you beat it?
</p>

</description><category>Python</category><category>XML</category><pubDate seconds="1066812502.54">2003-10-22T01:48:22-07:00</pubDate><comment-count>8</comment-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="405" id="634"><title>More XPath love</title><description>Patrick Lioi has also been giving <a href="http://patrick.lioi.net/archive/2003/10/21/200921">XPath a spin</a> with libxml and likes what he sees. 


</description><category>XML</category><category>Python</category><pubDate seconds="1066817456.61">2003-10-22T03:10:56-07:00</pubDate><trackback-count>0</trackback-count><comment-count>0</comment-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="406" id="635"><title>Other perspectives on programmers block</title><description><p>
As I suspected, programmers block is a common problem and many other people have written about it. Buzz 
Andersen posted a link to his <a href="http://www.scifihifi.com/weblog/software/ProgrammersBlock.html">very similar experiences</a>. From there I found some thoughts by <a href="http://www.russellbeattie.com/notebook/20030326.html#115058">Russell Beattie</a> and <a href="http://www.joelonsoftware.com/articles/fog0000000339.html">Joel Spolsky</a>. Russell looks at it as procrastination and points to another <a href="http://pythonowns.blogspot.com/2003_03_23_pythonowns_archive.html#91349488">post</a> that talks a little about that.

</p>
<p>
I think calling it procrastination is a common thing, but that's definitely not what it is. It feels that way, and I've certainly spent a lot of time kicking myself for procrastinating. The problem is deeper though and writing it off as procrastination makes the situation worse. Procrastination is something that you feel you should be able to control, "if you'd just stop being lazy". However programmers block is not about laziness, for me it's a fear. A fear of failing to live up to the expectations that you impose on your self.

</p>
<p>
Andrzej Telezynski said it pretty well in the comments to my previous <a href="http://www.xmldatabases.org/WK/blog/630?t=item#comment">post</a>, " "Perfectionism" is the evil. It is one of the dreams that never can be true, just a poison for the mind". I think perfectionism is what drives the creative process, but it's definitely both friend and foe.

</p></description><category>Python</category><category>XML</category><pubDate seconds="1066819601.17">2003-10-22T03:46:41-07:00</pubDate><comment-count>8</comment-count><trackback-count>0</trackback-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="429" id="659"><title>Installing libxml2 with Python on Panther</title><description>For the search engines, here's the proper incantation to get libxml2 to build the Python bindings for the default Python on Mac OS X Panther. I struggled with this because there's another copy of Python.h under /Developer and trying to build it against that doesn't work.

<pre><![CDATA[
./configure --with-python=/System/Library/Frameworks/Python.framework/Versions/2.3/
]]></pre>

</description><category>Python</category><category>XML</category><category>Mac OS X</category><pubDate seconds="1067537128.07">2003-10-30T11:05:28-07:00</pubDate><trackback-count>1</trackback-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="433" id="663"><title>Baking XML in the language</title><description><p>
This is a wish list item, call it a dream maybe, but I really want to see XML support baked directly into a programming language. Python in particular would be great. Here's what I want. 
</p>


<ul>
	<li>Seamless XML support. Never having to explicitly parse an XML document.</li>
	<li>XPath as a native language construct.</li>
	<li>Dynamic conversion between text and parsed representations of the XML.</li>
	<li>XPath manipulation for XML modifications.</li>
</ul>

 
<p>
Here's an example of the flavor that I'm looking for. This is pseudo Python though what I'm thinking may be considered un-pythonic. That's not my concern though, it's just a concept.

</p>
<pre><![CDATA[
doc = "<item><title>example</title><description>just an example</description></item>"
doc2 = "<item><title>example2</title><description>just another example</description></item>"

# get the title as a string
title = doc/item/title/text()
print title

# get the title as a node
title = doc/item/title
print title

# a collection of documents
docs = [doc, doc2]

# find all the titles in the collection as strings
titles = docs/item/title/text()
print titles

# find the node for the title that equals 'example'
titles = docs/item[title = 'example']/title
print titles

# find all items that contain the word another in their description
item = docs/item[contains(description, 'another')]
print item

# Use dynamic conversion to treat the XML as a string and 
# rename the description element to body
doc = re.sub("^description", "body", doc)
print doc

# append some new content to the body
doc/item/title/body += " with new content"
print doc

# Delete the title element
doc/item -= title
print doc

# append the new title
doc/item += "<title>new title</title>"
print doc

# delete the title again and then insert a new one before body
doc/item -= title
doc/item/body <= "<title>new title inserted before</title>"
print doc

# delete the title again and then insert a new one after body
doc/item -= title
doc/item/body => "<title>new title inserted after</title>"
print doc

]]></pre>

<p>
If you could run this program here's what you would get as output.
</p>

<pre><![CDATA[
example
<title>example</title>
["example", "example2"]
[<title>example</title>]
[<item><title>example</title><body>just an example with new content</body></item>]
<item><title>example</title><body>just an example</body></item>
<item><title>example</title><body>just an example with new content</body></item>
<item><body>just an example</body></item>
<item><body>just an example</body><title>new title</title></item>
<item><title>new title inserted before</title><body>just an example</body></item>
<item><body>just an example</body><title>new title inserted after</title></item>

]]></pre>

<p>
The XPath modification syntax is an experimental one I came up with sometime last year but never implemented. Here's how it translates.

</p>

<ul>
	<li>+= is append</li>
	<li>-= is delete</li>
	<li><![CDATA[<=]]> is insert before</li>
	<li>&gt;= is insert after</li>
	<li>= is replace</li>
	<li>~= is rename node</li>
</ul>


 
<p>
BTW, I am aware of one language implementation that does some of what I want. The XQuery implementation that's part of Sherlock on Mac OS X has the dynamic conversion between text and an in memory representation of the XML. It doesn't have a modification syntax though.

</p>
 


</description><category>XML</category><category>Python</category><pubDate seconds="1067577462.88">2003-10-30T22:17:42-07:00</pubDate><comment-count>19</comment-count><trackback-count>0</trackback-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="444" id="674"><title>Syncato 0.6 available</title><pubDate seconds="1067848457.3">2003-11-03T01:34:17-07:00</pubDate><description><p>
<a href="http://www.syncato.org">Syncato</a> 0.6 is now available for <a href="http://www.xmldatabases.org/files/syncato-0.6.tar.gz">download</a>. This release is a substantial improvement over the 0.5 release, but is still mainly aimed at people who are pretty technical. 
</p>
<p>
Syncato is the weblog system that runs <a href="http://www.xmldatabases.org">Inspirational Technology</a>. Its major distinguishing characteristic is that it is based heavily around the concept of manipulating XML fragments via XPath and XSL-T. This principal is used to implement the system as well as being exposed to the world via XPath in the URL. Using XML in this way results in a very powerful system for the storage of all kinds of data. 
</p>
<p>
The data storage architecture is an open container for any type of XML fragment that you want to throw into it. The system then provides the ability to pick from that container whatever you want to include within your posts. This mechanism also encourages you to include richer markup within you posts. Syncato basically encourages you to either make up tags that mean something specific to you or to use standard markup in a way that provides some additional meaning. 
</p>
<p>
For example, in my posts I sometimes recommend products and then include a link to Amazon for the product. To make this simpler I created a new "asin" tag that includes the Amazon product identifier. When the site is rendered the tag gets converted into the appropriate markup for Amazon product links. However, beyond that it also enables you to do interesting things like get a <a href="http://www.xmldatabases.org/WK/blog/item[//asin]?t=front-page">page containing all posts that have recommended products on Amazon</a>. This kind of thing is all accomplished via XPath in the URL.
</p>
<pre><![CDATA[
http://www.xmldatabases.org/WK/blog/item[//asin]?t=front-page
]]></pre>
<p>
This is just a simple example, but the possibilities are completely open depending on how you markup your posts.
</p>
<p>
The single biggest change in the 0.6 release is the inclusion of a file based database in addition to the<a href="http://www.sleepycat.com/products/xml.shtml"> Berkeley DB XML</a> database. This provides a much simpler way to get an initial system up and running. The dependencies are reduced to just Python, libxml, libxslt, Webware and a webserver. It's still harder to install then I'd like, but it's getting better. The file database works well for small data sets up to a few hundred entries. From there you can then update to Berkeley DB XML to take advantage of its indexing capabilities. Since everything is XML it's pretty easy to convert from one database type to another.
</p>
<p>
The other notable change in this release is the inclusion of the Blogger and Metaweblog APIs. <a href="http://randomthoughts.vandorp.ca">Darryl VanDorp</a> stepped up to the plate and got them working just in time to be included.
</p>
<p>
Here's a list of what else changed this time around.
</p>


<ul>
	<li>Added comment support.</li>
	<li>Moved weblog pings into a separate thread.</li>
	<li>Made pings generic so that any site that supports the weblogs.com interface
can pe pinged.</li>
	<li>Added technorati pings to the default configuration.</li>
	<li>Added a very rudimentary HTML administration interface.
(Just add and edit entries)</li>
	<li>Added the PathUpdate API to enable document contruction and modification
using XPath to select nodes.</li>
	<li>Added category RSS feeds</li>
	<li>Added a file based database to make the software easier to get up and running.</li>
	<li>The file based database is the default out of the box.</li>
	<li>Began rearranging the XSL files to start separating user styles from
system styles.</li>
	<li>Initial Blogger and Metaweblog API implementations. (thanks Darryl VanDorp)</li>
	<li>Changed the command line scripts to use the web interface instead of accessing
the database directly.</li>
	<li>Switched categories to key off of title instead of id.</li>
	<li>Substantial improvements in the stability of the Berkeley DB XML backend.</li>
	<li>Changed the directory structure for servlets. There are now three types based
on access restrictions.</li>
</ul>

 





</description><category>Syncato</category><category>XML</category><category>XML Databases</category><category>Web Services</category><category>Python</category><comment-count>5</comment-count><trackback-count>0</trackback-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="482" id="712"><title>Coming features in Syncato 0.7</title><description><p>
I've begun updating the list of features that will be coming in the next release of <a href="http://www.syncato.org">Syncato</a>. I'll be adding to the list as I get things working. I'm not listing anything until I actually have it working. This post will update automatically as I add features on the main page. 
</p>
<xpath-query>/page[@id=508]//ul[@id='coming-features']</xpath-query>
 
<p>
I think the next release will pretty much complete the list of basic weblog features that Syncato should have, i.e. the stuff that most systems already do. Syncato already does a whole bunch of stuff that no other system does. Going forward I'll be focusing on usability, in particular making the system easier to setup.
</p>


</description><category>Syncato</category><category>Web Services</category><category>XML</category><category>Python</category><pubDate seconds="1068390774.21">2003-11-09T08:12:54-07:00</pubDate><comment-count>0</comment-count><trackback-count>0</trackback-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="752" id="985">
  <title>PathUpdate API</title>
  <description>
    <p>In <a href="http://www.syncato.org">Syncato 0.6</a> I added a Python API for constructing and modifying XML fragments using XPath specifiers. So far this has proven to be a really powerful way of working with XML fragments the way Syncato does. 
</p>
    <p>The API is pretty simple.
</p>
    <pre>
<![CDATA[class PathUpdate:            
    def addNode(self, path, content = None, markup = 0, createBase = 1):
            
    def updateNode(self, path, content = "", markup = 0):
                
    def removeNode(self, path):
            
    def insertNodeBefore(self, path, nodeName, content=None):
        
    def insertNodeAfter(self, path, nodeName, content=None):
            
    def getDocument(self):
        
    def serialize(self):

]]>
    </pre>
    <p>You can use it to create a new document. Here's an example to create a simple weblog post.
</p>
    <pre>
<![CDATA[doc = PathUpdate()

doc.addNode("/item/title", "A sample title")
doc.addNode("/item/description", "Some body content with <markup>embedded</markup>", 1)

]]>
    </pre>
    <p>Printing this out then gives you a document that looks like this.
</p>
    <pre>
<![CDATA[<item>
<title>A sample title</title>
<description>Some body content with <markup>embedded</markup></description>
</item>

]]>
    </pre>
    <p>Modifying is also easy
</p>
    <pre>
<![CDATA[doc = PathUpdate(libxml2.parseDoc("<item><title>example</title></item>") 

doc.updateNode("/item/title", "Another example")

]]>
    </pre>
    <p>Of course you could also use a more complex query to select the node. If the query selects multiple nodes then all will be updated. Pretend this example has lots of title elements, but we only want to change those containing the word "example".
</p>
    <pre>
<![CDATA[doc = PathUpdate(libxml2.parseDoc("<item><title>example</title></item>") 

doc.updateNode("/item/title[contains(., 'example')]", "Another example")

]]>
    </pre>
    <p>Right now the code is available as part of Syncato, but isn't tied to Syncato at all. It just depends on libxml2. Once it matures a little more I'll probably make the API available as a standalone download since it's quite powerful. It basically gives you an XML update language that uses Python syntax. 
</p>
  </description>
  <category>Syncato</category>
  <category>XML</category>
  <category>Python</category>
<pubDate seconds="1068910503.1">2003-11-15T08:35:03-07:00</pubDate><comment-count>1</comment-count><trackback-count>0</trackback-count></item>
<item xmlns:dbxml="http://www.sleepycat.com/2002/dbxml" dbxml:id="776" id="1020">
  <title>Syncato 0.7 Released</title>
  <description>

  <p><a href="http://www.syncato.org">Syncato</a> 0.7 is now available for download. Syncato is the Python and XML based weblog software that runs this site. In addition to new features, performance increases and bug fixes, this release also brings a change in the license of the software. Previous releases were released under an Apache style license. Syncato 0.7 and all future releases are being made under a <a href="http://www.syncato.org/WK/blog/Syncato_License.page">license</a> derived from the Sleepycat license. This is still an <a href="http://www.opensource.org">Open Source</a> license and the terms are very simple. The main difference is that it does restrict commercial redistribution of the code unless full source of any derivative work is also made available. 
</p>
  <p>Here's the list of changes in this release.
</p>
  <ul>
    <li> Added trackback support
</li>
    <li> Added trackback autodiscovery on post pages
</li>
    <li> Added remote-xpath-query and remote-content include tags that allow you to include remote XML content into your posts.
</li>
    <li> Greatly improved the HTML admin interface.
</li>
    <li> Added comment and trackback spam URL blacklist support
</li>
    <li> Refactored the stylesheet locations to separate system and user stylesheets. All stylesheets in dist/stylesheets are intended to be updated any time a new version is released. User customizations can be made by overriding any   of the templates from the stylesheets in that directory. User styles are stored in the top level syncato stylesheet directory.
</li>
    <li> Reworked the URL scheme to add the ability to use post titles to provide more descriptive URLs.
</li>
    <li> Changed output from XSL process to generate XML instead of outputing HTML.
</li>
    <li> Added a new URL parameter c to enable content queries. These are XPath queries run on rendered content. This allows you to extract fragments from the  HTML result.
</li>
    <li> Added configuration options to turn url xpath queries and content queries off.
</li>
    <li> Changed summarize function of WeblogXslExtension to no longer require sgmllib.
</li>
    <li> Fixed summarize so that it expands embedded tags prior to doing the summary.
</li>
    <li> Lots of cleanup to simplify the XSL files.
</li>
    <li> Added additional indexes to the DB XML backend. This tuning provides a substantial improvement in performance when running the latest version of DB XML.
</li>
    <li> Renamed the root element on category definitions from category to  category-def. This was done to take better advantage of the indexing  facilities of DB XML. There's a script update.py that will update an existing site
</li>
  </ul>

</description>
  <category>Syncato</category>
  <category>XML</category>
  <category>XML Databases</category>
  <category>Web Services</category>
  <category>Python</category>
<pubDate seconds="1069747899.62">2003-11-25T01:11:39-07:00</pubDate><comment-count>6</comment-count><trackback-count>0</trackback-count></item>
<item id="1042">
  <title>Cocoa applications in Python</title>
  <description>

  <p>Ryan Wilcox has wrtten an interesting <a href="http://www.wilcoxd.com/blog/archives/000033.html">piece</a> on building Mac OS X Cocoa applications in Python with PyObjC. Digging more into PyObjC is still very much on my todo list.
</p>

</description>
  <category>Mac OS X</category>
  <category>Python</category>
<pubDate seconds="1070157963.52">2003-11-29T19:06:03-07:00</pubDate><trackback-count>0</trackback-count></item>
<item id="1052">
  <title>Groovy is groovy</title>
  
  
  
<pubDate seconds="1070397303.47">2003-12-02T13:35:03-07:00</pubDate><description>

  <p>A couple days ago I came across a new scripting language for the Java platform called <a href="http://groovy.codehaus.org/index.html">Groovy</a>. This language is pretty slick and is actually approximating what i was talking about in my post about <a href="http://www.xmldatabases.org/WK/blog/663_Baking_XML_in_the_language.item">baking XML into the language</a>. It doesn't use XPath, but does have a language <a href="http://wiki.codehaus.org/groovy/PathExpressionLanguage">GPath</a> that is based on the base syntax of the language and can be used to query any in memory data structure. The language does have some built in XML support and as part of the syntax enables a Groovy program to be treated as an <a href="http://groovy.codehaus.org/markup.html">alternative markup language</a>. Very lisp like, but also very cool to see in a Java like language.
</p>
  <p>Since Groovy targets the Java platform it can use any java classes and provides nice builtins for lists, tuples and closures. Overall a very promising looking language. In a lot of ways it does the same thing as <a href="http://www.jython.org">Jython</a>, but the features like GPath and GroovyMarkup are pretty compelling.
</p>

</description><category>Programming</category><category>Python</category></item>
<item id="1053">
  <title>The pain of over abstraction</title>
  <description>

  <p>While playing around with groovy it becomes painfully obvious how Java classes are often way too hard to use in a scripting context. Here's an example that uses Groovy to parse an XML file using Saxon and then run an XPath query against it.
</p>
  <pre>
<![CDATA[
#!/usr/bin/env groovy

import net.sf.saxon.xpath.XPathEvaluator
import org.xml.sax.InputSource;
import javax.xml.transform.sax.SAXSource;
import java.io.File;

is = new InputSource(new File("config.xml").toURL().toString());
ss = new SAXSource(is);
xpe = new XPathEvaluator(ss);

results = xpe.evaluate("/blog/base-url");

for (result in results) {
    println(result.getStringValue())
}

]]>
  </pre>
  <p>Not too bad I guess and a hell of a lot better then straight Java, however, here's how you do the same thing in Python with libxml.
</p>
  <pre>
<![CDATA[
#!/usr/bin/env python

import libxml2

doc = libxml2.parseFile("config.xml")

results = doc.xpathEval("/blog/base-url")

for result in results:
        print result.content

]]>
  </pre>
  <p>The Python is vastly more direct and to the point, even in this simple example the Java API is saddled with way too much abstraction. This drives me insane with Java, you can of course wrap whatever you want to gloss over the abstractions, but I really don't get why API designers for Java so adamantly refuse to make the common cases easy. I was there once myself, I had a wee bit to do with creating the overly abstracted mess that is the <a href="http://www.xmldb.org/xapi/xapi-draft.html">XML:DB API</a>. I regret that design every time I look at it. it could have been soooo much easier to use. Why isn't it? Ugg, who knows, maybe that wouldn't have been enough Java like.
</p>
  <p>Anyway, to reinforce the point that the problem is with the API designs, here' s the Groovy example re-implemented in Jython.
</p>
  <pre>
<![CDATA[
#!/usr/bin/env jython

from net.sf.saxon.xpath import XPathEvaluator
from org.xml.sax import InputSource;
from javax.xml.transform.sax import SAXSource;
from java.io import File;

input = InputSource(File("config.xml").toURL().toString())
ss = SAXSource(input)
xpe = XPathEvaluator(ss)

results = xpe.evaluate("/blog/base-url")

for result in results:
    print result.getStringValue()

]]>
  </pre>
  <p>You might complain that Saxon doesn't have the best API, but all the Java XPath tools are bad, most of them much worse. DOM4j is probably a little better then Saxon, but not substantially.
</p>
  <p>Looking at these APIs it's also obvious why so many programmers like to moan about how hard XML is. Who can blame them when it takes four classes from four different packages just to parse an XML file. We won't even talk about the W3C DOM. We also won't talk about the fact that the Groovy example hides the fact that those APIs throw checked exceptions.
</p>
  <p>Oh yeah, how about serializing a document back to text? With libxml it's just doc.serialize(). How do you do it with your Java API? Honestly, I really don't even know with Saxon, but I know it takes a hell of a lot more then one method call. It sure did when working with Xerces and I could never remember how to do it without looking it up.  
</p>
  <p>I used to love Java, I also used to think Java was THE language for working with XML. I don't believe that anymore. Sure it's great to have an API that can have any individual component replaced, but that makes the API also have a massive barrier to actually writing code with it. Most Java APIs make the hard stuff possible, but they've really lost sight of the idea that the easy stuff should be easy. 
</p>

</description>
  <category>Programming</category>
  <category>Python</category>
  <category>Java</category>
<pubDate seconds="1070399771.46">2003-12-02T14:16:11-07:00</pubDate><comment-count>5</comment-count><trackback-count>1</trackback-count></item>
<item id="1068">
  <title>Playlist to XML</title>
  
  
  
  
  
  
<pubDate seconds="1070616825.66">2003-12-05T02:33:45-07:00</pubDate><description>

  <p>Since <a href="http://www.syncato.org/">Syncato</a> is an XML microcontent management system the <a href="http://www.xmldatabases.org/WK/blog?t=category&amp;a=Mix+Playlists">playlists</a> I've been posting are of course XML data like everything else in Syncato. To create the lists I use iTunes to create a playlist, fill it with the songs and then extract the playlist using a combination of Python and Applescript. This could of course be accomplished with just Applescript, but I'm much more comfortable with Python then I am with Applescript. This script is actually mostly Applescript since it was originally part of a larger Python program. 
</p>
  <pre>
<![CDATA[#!/usr/bin/python
#
# A simple script to get a playlist from iTunes and convert it to XML

import os, sys

if (len(sys.argv) != 2):
    print "Usage: playlistToXML.py playlist"
    sys.exit()
    
playlist = sys.argv[1]

# Applescript to get the content of  playlist in XML format..
getPlaylist = """tell application "iTunes"
	set thePlaylist to (user playlist \"""" + playlist + """\")
	set allsongs to (get name of every track of thePlaylist)
	set artists to (get artist of every track of thePlaylist)
	set albums to (get album of every track of thePlaylist)
	set trackTime to (get time of every track of thePlaylist)

    set songs to "<songlist>"
	repeat with i from 1 to (count of items in allsongs)
		set songs to songs &amp; "<song><title>" &amp; (item i in allsongs) &amp; "</title>"
		set songs to songs &amp; "<artist>" &amp; (item i in artists) &amp; "</artist>"
		set songs to songs &amp; "<album>" &amp; (item i in albums) &amp; "</album>"	
        set songs to songs &amp; "<length>" &amp; (item i in trackTime) &amp; "</length>"
		set songs to songs &amp; "</song>"
	end repeat
	set songs to songs &amp; "</songlist>"
end tell
"""
# Read the contents of the playlist from iTunes
content = os.popen("osascript -e '" + getPlaylist + "'").read()

print content
]]>
  </pre>
  <p>I haven't really had much time to experiment and develop the microcontent aspect of Syncato, I've been rather caught up with other things. There are a lot of interesting things that can be done with it, but it will take sometime to build the necessary concepts and tools. Posting playlists is fun, but isn't the most compelling thing that can be done. We'll see what happens over the coming months as I get more of the pieces in place.
</p>

</description><category>Syncato</category><category>Microcontent</category><category>XML</category><category>Python</category><category>Mac OS X</category><comment-count>8</comment-count><trackback-count>1</trackback-count></item>
<item id="1094">
  <title>OOP over the top</title>
  <description>

  <p>From <a href="http://www.hole.fi/jajvirta/weblog/20031206T2101.html">Jarno Virtanen</a>I found a link to an article titled <a href="http://csis.pace.edu/~bergin/patterns/ppoop.html">Understanding Object Oriented Programming</a>. Wow, all I can say is go read it and then you'll know exactly how not to build a maintainable system. I'll refer you back to my post on the <a href="http://www.xmldatabases.org/WK/blog/1053_The_pain_of_over_abstraction.item">pain of over abstraction</a>. In that post I was criticizing the design of many Java APIs, especially XML APIs, however this is really a general problem with OO development. Fancy object oriented architectures have become the goal and this article maybe makes that point more clearly then anything I could ever say. It's representative of the thinking from a few years ago (written in 2000), and shows us just how much damage we now have to undo. It basically says that the simple solution that just works is wrong and will be unmaintainable. Maybe that's true, maybe it's not, nowhere does the article consider the question of whether or not that code actually needs to be that generic. It simply says that the simple solution is bad and that the seven class monster they came up with is the right solution. Talk about doing a disservice to students trying to learn how to build solid computer systems. 
</p>
  <p>OO techniques are a tool, they are not an end goal. Starting to design a system to achieve OO purity is the fastest way to build a system that will be ten times more complex then it likely needs to be. This article was actually written in 2000 and thankfully Agile development methods that understand this distinction have been gaining substantial mind-share since then. Hopefully Pace University and King's College London are no longer teaching their students that this is the "right" way.
</p>
  <p>BTW, Simon Willison has posted an <a href="http://simon.incutio.com/archive/2003/12/05/dataDriven">alternative solution</a> and says "smart data-driven programming beats over-engineered class-based programming any day of the week". All I can say is, I agree completely. Programmers like to write code, and personally I think write too much of it, way too much of it. Data-driven programming is a method that's been lost in all the OO hype, but it works, and I believe it's going to play an increasingly important role going forward. This will especially be driven by XML ubiquity. <a href="http://www.syncato.org">Syncato</a> is my experiment in exploring XML based data driven programming.
</p>
  <p>In that spirit, here's my solution to the problem using XML, Python and Simon's mythical System.getProperty. Using XML here is of course overkill too, but it solves their original problem in a much more maintainable manner, requiring zero code changes to add a new system.
</p>
  <p>An XML description.
</p>
  <pre>
<![CDATA[<os-list>
    <os>
        <name>Windows NT</name>
        <name>Windows 95</name>
        <name>Windows CE</name>
        <message>This is a Windows box and therefore bad.</message>
    </os>
    <os>
        <name>SunOS</name>
        <name>Linux</name>
        <message>This is a UNIX box and therefore good.</message>
    </os>
</os-list>
]]>
  </pre>
  <p>And a simple program to glue the pieces together.
</p>
  <pre>
<![CDATA[#!/usr/bin/env python
import libxml2

list = libxml2.parseFile("os.xml")

name = System.getProperty("os.name")
message = list.xpathEval("//os[name = '" + name + "']/message")
if (len(message) > 0):
    print message[0].content
else:
    print 'This is not a box.'
]]>
  </pre>
  <p>This particular example was contrived in the original paper and it's contrived here too, however when you teach OO developers to think code first, you end up with lots and lots of code. Want to know the secret to building maintainable systems? Quit writing so much source code. Ask your self if that fancy OO technique you're about to apply is really necessary or if a simpler data-driven solution can solve the same thing. I'll argue every time that if a simple XML file can eliminate a dozen classes, you need a damn good reason not to use it. That's not saying that there aren't times when it's inappropriate. Like everything else, this is just a tool too, but I believe it's an under-used and extremely powerful tool. 
</p>
  <p>Once upon a time we understood this, we used to drive systems off the data model, now it seems everything has to be objects. This presents a problem since relational data models have presented a persistent mapping problem into object oriented domains. And many of the techniques developed to solve the problem are some of the worst offenders of the too much code phenomenon. EJB entity beans are a pretty good example of this. Forcing an OO layer between the program and its persistence introduces so much overhead that it's often just easier to write a dozen classes to solve the problem. XML now provides you the ability to start small and scale up as needed. The model is always the same no matter where the data comes from.
</p>
  <p>XML is about options. For instance in this silly example I could have certainly used a simple tab delimited file or some type of properties file. However, there are benefits to this being XML. Obviously, XPath is a big one, but so is the ability to change the underlying data storage technique. To your application it's just XML, but underneath it could be coming from the file system, over the network via HTTP, from a native XML database or it could be an assembled document from an RDBMS, an LDAP server or just about anywhere. To your application, outside of changing the location of where to read the data, it makes no difference. This provides the ability to evolve the system over time well beyond what something like a properties file would enable. To boot, using XPath, it probably even takes less code to process. Could you do all this with a properties file? Sure, but you'd have to build it all your self because everybody else is using XML.
</p>
  <p>The key here? Don't insist on putting a fancy OO layer on top of the XML. In some cases that will help, but in most cases it's just overhead. XML has powerful tools, learn how to leverage them. XPath in particular provides a tremendous amount of power for very little effort. It's not suitable in every situation, but is a very good way to bootstrap a simple solution.
</p>

</description>
  <category>Programming</category>
  <category>Python</category>
  <category>Java</category>
  <category>XML</category>
<pubDate seconds="1070951843.05">2003-12-08T23:37:23-07:00</pubDate><trackback-count>4</trackback-count><comment-count>10</comment-count></item>
<item id="1148">
  <title>HelloWorld PyObjC</title>
  
  
  
<pubDate seconds="1071524998.29">2003-12-15T14:49:58-07:00</pubDate><description>

  <p>Yesterday I finally sat down and got <a href="http://pyobjc.sourceforge.net/index.php">PyObjC</a> working on Panther. I had been having some problems with it earlier until I realized I was installing the Jaguar version on Panther. Doh! If you want to install it, don't download the installer, it doesn't work on Panther. That isn't real clear on the download page. Anyway, I put together my first program with it. So here's my PyObjC version of a first program.
</p>
  <p><img src="http://www.xmldatabases.org/screens/helloworld.jpg" alt="http://www.xmldatabases.org/screens/helloworld.jpg"/> 
</p>
  <p>Yep, that's a very, very rudimentary web browser. That's how simple Cocoa makes this stuff. Doing that was just as easy as throwing up a simple text area to say "hello world". Of course it helps that I already know Cocoa, but ... anyway, here's the Python code for creating a very, very simple web browser using WebKit and PyObjC.
</p>
  <pre>
<![CDATA[from PyObjCTools import NibClassBuilder, AppHelper
import WebKit
from Foundation import *
from AppKit import *

NibClassBuilder.extractClasses("MainMenu")

# class defined in MainMenu.nib
class MyObject(NibClassBuilder.AutoBaseClass):
    # the actual base class is NSObject
    # The following outlets are added to the class:
    # url
    # webview

    def loadURL_(self, sender):
        urlString = self.url.stringValue()
        url = NSURL.URLWithString_(urlString)
        request = NSURLRequest.requestWithURL_(url)
        self.webview.mainFrame().loadRequest_(request)
        
if __name__ == "__main__":
    AppHelper.runEventLoop()
]]>
  </pre>

</description><category>Mac OS X</category><category>Python</category><comment-count>3</comment-count><trackback-count>1</trackback-count></item>
<item id="1162">
  <title>URL handlers with PyObjC</title>
  <description>

  <p>Following up on my previous post about writing Cocoa applications to <a href="http://www.xmldatabases.org/WK/blog/1154_Handling_URL_schemes_in_Cocoa.item">handle custom URL schemes</a>, I wanted to add on how to do it with a PyObjC Python application. I'm definitely still getting up to speed on PyObjC so there may be an easier way to do this, but I was able to get it to work. All the scripting dictionary and Info.plist settings are the same, you just need to add a Python implementation of URLCommandHandler. The tricky part is getting the Python URLCommandHandler object to be made available to the Objective C runtime so that it can be linked up with the incoming apple event. 
</p>
  <p>The way I did that was to create a Nib file that contained a subclass of NSScriptCommand named URLCommandHandler. NSScriptCommand is not part of the normal list of classes you can subclass in Interface Builder so you need to tell IB to read the header file for it, it's part of Foundation.framework. Once you have that defined you can use the Nib in the same way as usual for PyObjC and the Objective C runtime will be able to see your Python class. You just need to create the subclass, there aren't any other connections involved. Because of this, I'm guessing there's probably a way to do this without using IB to make the connection. I just haven't figured out how yet.
</p>
  <p>The Python class is really simple.
</p>
  <pre>
<![CDATA[
from PyObjCTools import NibClassBuilder, AppHelper
from Foundation import *
from AppKit import *

NibClassBuilder.extractClasses("MainMenu")

class URLHandlerCommand(NibClassBuilder.AutoBaseClass):  
    def performDefaultImplementation(self):
        urlString = self.directParameter()
    
        print "url = %s" % urlString

        return None

if __name__ == "__main__":
    AppHelper.runEventLoop()
]]>
  </pre>
  <p>It's actually very easy once you know how to do it. Doing this should also enable you to add general AppleScript support to Cocoa applications written in Python. 
</p>

</description>
  <category>Mac OS X</category>
  <category>Python</category>
<pubDate seconds="1071622874.5">2003-12-16T18:01:14-07:00</pubDate><comment-count>4</comment-count><trackback-count>1</trackback-count></item>
<item id="1211">
  <title>OO versus XML + agile programming languages?</title>
  <description>

  <p>Over on his O'Reilly Network blog Uche Ogbuji <a href="http://www.oreillynet.com/pub/wlg/4115">took issue</a> with my <a href="http://www.xmldatabases.org/WK/blog/1094?t=item">use of XML</a> in my response to the extreme use of OO. The problem that I face is that I'm not a Python programmer, even though I program in Python, just as I was never a Java programmer even though I programmed in Java, nor was I a Perl programmer when I programmed in Perl. Languages are just tools. Data, however, is different. It has a permanence that exceeds the bounds of a particular programming language and to me placing data within the syntax of a particular programming language is not necessarily a good thing. Like Uche, I believe that dynamic languages are the way forward, however I also believe that we need to weaken the coupling between a particular language and the actual solution to a problem to whatever degree we can. 
</p>
  <p>As for the specifics of using XML in that case it was just an attempt to show it as an option. Simon Willison had already demonstrated a solution exactly like Uche is advocating, so I simply wanted to add on another perspective that pulled the data out of the language. XML was the easiest way for me to do that. When I mentioned XML was overkill what I was thinking was that it was overkill compared to using something like a Java style property list file, not compared to expressing the data in a programming language. Whether the use of XML in this case was or was not a good idea is an unanswerable question without considering much more context (that doesn't exist) so we won't worry about it anymore.
</p>
  <p>Oh yeah, I've also seen a few people say that I'm an OO hater or some such nonsense. Like everything, OO is a tool, sometimes it's good, sometimes it's not. The same applies to data oriented programming and XML. Unfortunately since I'm experimenting heavily with pushing the use of XML and data oriented programming to extremes, my posts often come off pushing the techniques more then I would when building a real world production application. That's the bias of my writing, simply because that's what I'm interested in and that's what I want people to be more aware of. I do believe we've gone too far with OO and that it is getting over used and is resulting in systems that are far too complex, but that's a long way from hating OO. </p>

</description>
  <category>XML</category>
  <category>Python</category>
  <category>Programming</category>
<pubDate seconds="1073189370.85">2004-01-03T21:09:30-07:00</pubDate><trackback-count>1</trackback-count><comment-count>1</comment-count></item>
<item id="1274">
  <title>Writing libxslt extension modules in Python</title>
  <description>

  <p>A while back I wrote up a quick post on writing<a href="http://www.xmldatabases.org/movabletype/archives/000291.html">libxslt extension functions in Python</a>. Writing extension functions allows you to easily call python code from within an XSL-T stylesheet. I wanted to add a little more detail to that post and show how you can build extension modules instead of just single functions. As far as I know there isn't any documentation as part of the <a href="http://xmlsoft.datenkueche.com/XSLT/">libxslt</a> distribution.
</p>
  <p>Here's an example program.
</p>
  <pre>
<![CDATA[
#!/usr/bin/env python
#
# Sample libxslt extension functions
import libxml2, libxslt

def countChars(ctx, content):
    if (isinstance(content, str)):
        return str(len(content))
        
    return str(0)

def firstChar(ctx, content):
    if (isinstance(content, str)):
        return str(content[0])
        
    return ""
    
libxslt.registerExtModuleFunction("countChars", "http://www.xmldatabases.org/extension", countChars)
libxslt.registerExtModuleFunction("firstChar", "http://www.xmldatabases.org/extension", firstChar)

data = """
<doc>This contains 27 characters</doc>
"""
        
styledoc = libxml2.parseFile("style.xsl")
style = libxslt.parseStylesheetDoc(styledoc)
doc = libxml2.parseDoc(data)
result = style.applyStylesheet(doc, None)
            
print style.saveResultToString(result)
                           
doc.freeDoc()
style.freeStylesheet()

]]>
  </pre>
  <p>This example registers two functions under the namespace "http://www.xmldatabases.org/extension". To make them part of a module you have to call the libxslt.registerExtModuleFunction to register them with the libxslt environment. You can register as many functions as you want this way. The first parameter is the name you use to call the function from within libxslt, the second is the XML namespace URI that identifies the module and the third is a Python callable that implements the function. All functions with the same namespace URI are considered part of the same module.
</p>
  <p>The functions always take at least one argument, the xpath parser context. However, you can add additional arguments to pass other data from the style sheet to your function. These arguments will come in as various different types based on how they're passed from XSL-T. For instance they could be a libxml2 node, a list, or a string. In this example I convert the arguments to a string within the XSL-T before passing the data to the function. If I didn't do that I'd have to convert the argument into a node and then get the content of the node as a string.
</p>
  <p>The same consideration must be given to what you return from the function. In this case, both functions convert their results to strings, but they could also return libxml2 nodes or lists of nodes that will be inserted into the result document.
</p>
  <p>Here's the associated stylesheet that uses the functions.
</p>
  <pre>
<![CDATA[
<xsl:stylesheet
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:extension="http://www.xmldatabases.org/extension"
        extension-element-prefixes="extension"
        xsl:version="1.0">
        
    <xsl:template match="/doc">
        <xsl:value-of select="extension:countChars(string(.))"/>
        <xsl:value-of select="extension:firstChar(string(.))"/>
    </xsl:template>
    
</xsl:stylesheet>

]]>
  </pre>
  <p>There are two things you have to do before you can use the functions. 
</p>
  <ol>
    <li> Declare the namespace URI that you used to define the functions within the libxslt environment. You can bind this namespace URI to any prefix you want. 
</li>
    <li> Declare the prefix that you chose as an extension element prefix by adding it to the extension-element-prefixes attribute. 
</li>
  </ol>
  <p>Once you do both of those things you can call the functions like any other XSL-T functions. Just make sure you pass types that your functions know how to handle. It's obviously a good idea for your functions to explicitly convert the different types if they can. </p>

</description>
  <category>Python</category>
  <category>XML</category>
<pubDate seconds="1073806779.19">2004-01-11T00:39:39-07:00</pubDate><comment-count>3</comment-count><trackback-count>1</trackback-count></item>
<item id="1326">
  <title>pybsddb 4.2.4 released</title>
  <description>

  <p>There's a new release of <a href="http://sourceforge.net/project/showfiles.php?group_id=13900&amp;package_id=12759">pybsddb</a> available. 4.2.4 is a necessary release if you want to use Berkeley DB 4.2 with Python. Berkeley DB 4.2 is recommended for use with <a href="http://www.sleepycat.com/products/xml.shtml">Berkeley DB XML</a> 1.2 and without this pybsddb release Python crashes with DBXML 1.2 and DB 4.2.
</p>
  <p>Because I haven't had Python working with my Berkeley DB XML 1.2 install until now, I haven't yet verified that <a href="http://www.syncato.org">Syncato</a> will work with it.
</p>

</description>
  <category>Python</category>
  <category>XML Databases</category>
  <category>Syncato</category>
<pubDate seconds="1074282301.36">2004-01-16T12:45:01-07:00</pubDate><trackback-count>0</trackback-count><comment-count>0</comment-count></item>
<item id="1328">
  <title>Syncato and Berkeley DB XML 1.2.0</title>
  
  
  
  
<pubDate seconds="1074284724.21">2004-01-16T13:25:24-07:00</pubDate><description>

  <p>I can now confirm that <a href="http://www.syncato.org">Syncato</a> does NOT work with DB XML 1.2.0. Actually, it looks like the Python bindings for deleteDocument and queryWithXPath in DB  XML 1.2.0 have problems with transactions. So if you want to use transactions wait for DB XML 1.2.1 which will have a fix. The Python bindings seem to work fine otherwise. Waiting for 1.2.1 will also be necessary for Syncato to run.
</p>
  <p>Update: I've confirmed that Syncato will work without changes when DB XML 1.2.1 is released.
</p>

</description><category>Syncato</category><category>XML Databases</category><category>Python</category><comment-count>0</comment-count><trackback-count>0</trackback-count></item>
<item id="1693">
  <title>IronPython</title>
  
  
<pubDate seconds="1087441314.96">2004-06-16T22:01:54-07:00</pubDate><description>

  <p>The last couple days I've been playing around with <a href="http://www.go-mono.com/">Mono</a> Beta 2 on Mac OS X. It's kind of interesting to see things like ASP.net running directly on a Mac, pretty cool too. While poking around I also came across some promising looking work for implementing Python on top of the CLR called <a href="http://ironpython.com/">IronPython</a>. It's currently an "unreleased research prototype", but sounds like something that would be interesting to see in action. Performance on some basic benchmarks actually looks pretty surprising. Hopefully it moves beyond research prototype some day. 
</p>

</description><category>Python</category><comment-count>2</comment-count></item>
<item id="1961">
  <title>New programming languages</title>
  <description>

  <p>Lot's of interesting programming languages have been popping up lately. <a href="http://groovy.codehaus.org/">Groovy</a> has been one that initially caught my interest and now there's a new language called <a href="http://boo.codehaus.org/">Boo</a> that looks really interesting. Boo is a language that targets the CLR, but has syntax based on Python. It's not out to make a Python clone, just to have a similar syntax that can leverage the class library and other facilities available through the CLR. It's a really interesting language and runs just fine on top of Mono on Mac OS X.
</p>
  <p>Another language that looks interesting is from Microsoft Research and is now called <a href="http://www.research.microsoft.com/Comega/">Comega</a>. This is an evolution of the language that used to be referred to as X#. This language also targets the CLR and has integrated direct support for XML within the language syntax. I'm dying to have a usable language with tight XML integration so it's good to see progress in this area. Unfortunately, Comega is based around the concept of strongly typed XML which is something that I think defeats the whole point of using XML. Also in typical Microsoft fashion the compiler is available in a format that can only be installed on Windows. So far I haven't been able to try it out to see if it works on Mono. Well, actually I did try to install it on a Windows machine but the installer just silently fails so even that was unsuccessful. I suspect it's looking for the .Net framework or something else that isn't installed on that machine, but there's no information at all on what it requires. Anyway, the compiler download isn't actually linked from the Comega site as far as I can tell so you have to go to the <a href="http://www.research.microsoft.com/research/downloads/default.aspx">download section</a> on the Microsoft Research site if you want to get it. If it turns out it will run on Mono I'd love to hear about it.
</p>

</description>
  <category>Programming</category>
  <category>Python</category>
<pubDate seconds="1090095315.93">2004-07-17T15:15:15-07:00</pubDate><trackback-count>0</trackback-count></item>
<item id="1964">
  <title>XPath based Python Dictionaries</title>
  <description>

  <p>In my "secret" efforts to finally make some real progress on <a href="http://www.syncato.org">Syncato</a> I just added a pretty cool feature to the Syncato XMLFragment API that allows you to treat an XML document sort of like a Python dictionary. Basically it allows you to use an XPath in place of the usual string key. This includes both reading and modifying the document. These definitely won't be interchangeable with Python dictionaries so call it an experiment if you must. My interest here isn't in being pythonic, it's in having maximum power and simplicity for using XML as a core application data structure.  Given how the Syncato internals are written this provides a very valuable tool.
</p>
  <p>It looks something like this.
</p>
  <pre><![CDATA[
        doc = """<item>
    <title>Test Post 1</title>
    <description>Just a simple post to get started.</description>
    <category>XML</category>
    <category>Java</category>
</item>"""

        fragment = XMLFragment(doc)
        
        print "title " + fragment["/item/title"]
        
        fragment["/item/title"] = "New title"
        print "title " + fragment["/item/title"]
               
        del fragment["/item/title"]
        print "title " + fragment["/item/title"]

        print "Category " + fragment["/item/category[1]"]
        print "Category " + fragment["/item/category[2]"]

        print "title " + fragment["/item/title[contains(., 'title')]"] 
]]></pre>
  <p>Running this you get output that looks something like this.
</p>
  <pre><![CDATA[
title Test Post 1
title New title
title 
Category XML
Category Java
Category XML
]]></pre>
  <p>The API also supports setting a base for a query so that if you always have the same beginning path you can make it even more convenient to work with the XML using the dictionary mechanisms.
</p>
  <pre><![CDATA[
        doc = """<item>
    <title>Test Post 1</title>
    <description>Just a simple post to get started.</description>
    <category>XML</category>
    <category>Java</category>
</item>"""

        fragment = XMLFragment(doc)
        fragment.setBase("/item/")
                
        print "title " + fragment["title"]
        
        fragment["title"] = "New title"
        print "title " + fragment["title"]
               
        del fragment["title"]
        print "title " + fragment["title"]

        print "Category " + fragment["category[1]"]
        print "Category " + fragment["category[2]"]

        print "title " + fragment["title[contains(., 'title')]"] 
]]></pre>

</description>
  <category>Python</category>
  <category>XML</category>
  <category>Syncato</category>
<pubDate seconds="1090105756.74">2004-07-17T18:09:16-07:00</pubDate><trackback-count>4</trackback-count><comment-count>0</comment-count></item>
<item id="2153">
  <title>WSGIKit - Python - Syncato</title>
  <description>

  <p>Ian Bicking has announced a new project called <a href="http://blog.colorstudy.com/ianb/weblog/2004/11/11.html#P179">WSGIKit</a> that implements <a href="http://www.python.org/peps/pep-0333.html">WSGI</a> and attempts to maintain <a href="http://webware.sourceforge.net/">Webware</a> compatibility. This looks really interesting. Just today I was thinking about moving <a href="http://www.syncato.org">Syncato</a> to a WSGI implementation so this may be the way to get started. </p>

</description>
  <category>Python</category>
  <category>Syncato</category>
<pubDate seconds="1100222182.46">2004-11-11T19:16:22-07:00</pubDate><comment-count>0</comment-count><trackback-count>0</trackback-count></item>
<item id="2170">
  <title>What's up with Syncato</title>
  <description><p>It's been kind of quiet on the <a href="http://www.syncato.org">Syncato</a> front for ... well for quite a while. I've recently seen a few rumblings around the net about the project being abandoned and I'm happy to say that's not the case. I ran into two problems with the development of Syncato that stalled progress. First I got the system to the point where it worked well enough for what I needed. It's been running this site for about a year now and I've been happy with it. This kind of took some of my drive away while I went and worked on other things. However, that wasn't the real problem. The real problem was too grand a vision for what I really wanted the system to do. I've actually been quietly chipping away at the system during this period, I was just making too many major changes to release anything. I'm still caught in that cycle as the next release is still in pieces on my hard drive. The good news is that I've made substantial progress over the past week and the basic system is once again running with a much more advanced set of features.
</p>

<p>The single largest change with the next release is that the Syncato system and the weblog application will be completely separated. This has been my major stumbling block for progress as I wanted Syncato to be a generic platform for developing XML data driven applications. This required a number of changes including adding support for multiple databases, an internal roll based security system, a reworked XSL templating system, completely reworked configuration system and an entirely new concept for running multiple applications under the same Syncato instance. I'm also converting the existing REST API to be more compatible with the ATOM API. The good news is that most of this work is done and I was finally able to run my first rudimentary application on the system last night. </p>

<p>The bad news is that the weblog application still has to be converted, of course it's also exciting to finally be moving on to that stage. While converting the weblog application I'm also converting it to use the ATOM data model and API. This means that the system will not be backwards compatible with the old data. Of course, it's all XML so XSL-T will be able to make the conversions.</p>

<p>There's still a lot of work to do before I'm ready to make another release, but I think the new system is really promising and could be quite cool once the kinks are worked out. Just don't ask me when the release will come. :-)</p></description>
  <category>Python</category>
  <category>Syncato</category>
  <category>XML</category>
<pubDate seconds="1100760911.23">2004-11-18T00:55:11-07:00</pubDate></item>
<item id="6530">
  <title>XML is done</title>
  <description><p>As I continue to examine what it is that has put me into a year long blogging lull, I want to take a closer look at the things I used to write about. First up is XML. </p>
<p>
I've been a big proponent for the use of XML and Syncato was an attempt to show the possibilities for what can be done when you build a system with XML data running from top to bottom. My experiments in that area have been quite successful, building and using Syncato for the last two years have definitely convinced me of  the value in this line of exploration. However, that's really an exploration in microcontent systems, semi-structured data and building a unified data model more than it is at pushing XML technology. It just happens that XML technology provided the most convenient toolkit for accomplishing what I envisioned.
</p>

<p>My XML technology toolkit primarily consists of three things, XML 1.0 (without DTDs), XPath 1.0 and XSL-T 1.0. Occasionally I'll use namespaces, but I really try to avoid it. Most of the other XML specs, especially XML Linking, XML Schema and XQuery are simply too complicated for their own good. And worse, with the introduction of XML Schema the W3C started a generation of new specs based around the concept of strongly typed XML. That's a concept that in my mind completely destroys the value of using XML. It would be OK if you could just take XML Schema or leave it, but it's now getting baked into the core of other technologies like XQuery, and all the WS-* crap which makes all that stuff an absolute pain in the ass to deal with. It's also causing developers to adopt the strongly typed XML concept and create system of despicable fragility, when they should be leveraging the flexibility of XML to build systems of surprising resilience.</p>

<p>So it seems that for me, the XML technology stack is done. Even though some of the new features added in XPath 2.0 and XSL-T 2.0 would be extremely useful to have, in fact REALLY useful. The complexity introduced by the specs relationship with W3C XML Schema is going to keep support out of just about every toolset I work with. Right now I'm working on projects in PHP, Perl, Python and Ruby, none of which has any support for XPath 2.0 or XSL-T 2.0 and it seems likely won't gain support for it anytime in the near future. So thanks to the W3C and the abomination that is XML Schema, XML is now in practical usage, done, and in many ways that's too bad. </p>
</description>
  <category>Python</category>
  <category>XML</category>
<pubDate seconds="1133591387.81">2005-12-03T00:29:47-07:00</pubDate><comment-count>3</comment-count><trackback-count>1</trackback-count></item>
<item id="6533">
  <title>Python hasn't held my interest</title>
  <description><p>Another thing I used to write about a fair bit was Python. Python is a great language and it's the language that I used to write <a href="http://www.syncato.org">Syncato</a>. However, I never really cared all that much about the Python language itself. For example, I've never had any interest in embracing the Pythonic way of doing things and I certainly never considered myself a Python programmer. For Syncato my goal was to actually shove the programming language into the background as much as possible and focus on seeing how much could be accomplished via data transformations using XSL-T. I had to write a fair amount of Python code to bootstrap the system, but the actual applications, like this blog, are about 80% XSL-T. I guess this is a testament to Python, as it allowed me to do what I needed without getting in the way and it had the XML tools available to accomplish what I envisioned. 
</p>
<p> I still like Python, but since I can't get excited about the language itself, I guess I just lost the motivation to write about the areas of Python that I did actually use. </p></description>
  <category>Python</category>
<pubDate seconds="1133610542.18">2005-12-03T05:49:02-07:00</pubDate></item>
<item id="10141">
  <title>Announcing Grid7 Labs - Revolutionizing side project execution</title>
  
<pubDate seconds="1141311424.65">2006-03-02T08:57:04-07:00</pubDate><description><p>It seems every developer you talk to these days has a side project of one kind or another. You know those little ideas for web sites that might make a few thousand a month in revenue. Some are intended to become companies, but most just generate some passive income for the developer. The problem is that most people don't usually have the skills to pull off these side projects on their own. I know I don't, but I do have a large number of little revenue generating side projects that I want to see constructed. For the projects that are big enough you can go out and raise angel funding or maybe even venture capital, but for those that aren't big enough, getting the ideas off the ground is a little tougher.
</p>
<p>So we're doing something about that and I can now announce the existence of my (and co-founder Sean Tierney's) new company Grid7, LLC.
Grid7 is a consulting and product development company and we recently introduced a new concept, the side project incubator, <a href="http://www.grid7labs.com">Grid7 Labs</a>.
</p>
<p>
<a href="http://www.grid7labs.com">Grid7 Labs</a> provides a marketplace where developers, designers, administrators and anyone else with skills to lend, can work together to help each other build out their side projects. It's a developer cooperative where everyone who participates shares in the revenue from the creations that become part of the Grid. 
</p>
<p>Grid7 itself provides the project management tools, hosting and other infrastructure services to further simplify the development of these projects. 
</p>
<p>The Grid also operates with a "community source model". Which means that within the grid all source code for the projects is open and free for use, but the source code is not made available outside the grid. The Grid will almost certainly produce some true Open Source code, but most of the projects won't make sense to be released that way.
</p>
<p>The labs private pilot program, running with a set of selected developers, is now in progress and over the next few months we'll be releasing more information and opening the doors to more people. However, right now we do have one more spot for a Ruby or Python developer. 
</p>
<p>If you have a side project that can generate reasonable revenue, but can't be pulled off on your own, Grid7 Labs may have the answer. Feel free to <a href="http://www.grid7labs.com/index.php?option=com_content&amp;task=view&amp;id=3&amp;Itemid=6">signup</a> so that we can notify you when we're ready to bring more people on board.</p></description><category>Programming</category><category>Python</category><category>General</category><comment-count>0</comment-count></item>
<item id="13240">
  <title>Available for consulting</title>
  <description>Just a quick note to make it known that I'm available for consulting work. My resume is available <a href="http://www.xmldatabases.org/resume.html">here</a>. I'm   a software architect with particular expertise on XML, XML databases, REST web services, general distributed systems design, blogging technology, content management systems and agile methodologies. I'm extremely versatile when it comes to technology, in fact, within the last year I've worked on projects implemented in Java, Perl, PHP, Python and Ruby. </description>
  <category>Mac OS X</category>
  <category>Programming</category>
  <category>Python</category>
  <category>XML</category>
<pubDate seconds="1143749446.31">2006-03-30T13:10:46-07:00</pubDate></item>
</results>