Third Time's a Charm

P1012748 So, we had a baby over the weekend =). 8 lbs 10 ounces, 3 1/2 hour labor @ Hillcrest hospital (where Chika was born as well).

Her name is Anyachiemeka Chibuzo Anastar Ogbuji.

I've created a flickr set for her pictures. This particular shot (to the left) is my favourite. I'm getting much better with my Olympus 300 e-volt. In particular I'm now able to anticipate the settings to use before taking any practice shots.

P1012808

Roschelle's mom asked me how it felt to be a father of 3 and I told her it feels less different everytime. But nevertheless, that doesn't make it any less of a miracle.

[Chimezie Ogbuji]

via Copia

EXSLT/XML/JSON complications

Bruce D'Arcus commented on my entry "Creating JSON from XML using XSLT 1.0 + EXSLT", and following up on his reply put me on a bit of a journey. Enough so that the twists merit an entry of their own.

Bruce pointed out that libxslt2 does not support the str:replace function. This recently came up in the EXSLT mailing list, but I'd forgotten. I went through this thread. Using Jim's suggestion for listing libxslt2 supported extensions (we should implement something like that in 4XSLT) I discovered that it doesn't support regex:replace either. This is a serious pain, and I hope the libxslt guys can be persuaded to add implementations of these two very useful functions (and others I noticed missing).

That same thread led me to a workaround, though. EXSLT provides a bootstrap implementation of str:replace, as it does for many functions. Since libxslt2 does support the EXSLT functions module, it's pretty easy to alter the EXSLT bootstrap implementation to take advantage of this, and I did so, creating an updated replace.xsl for processors that support the Functions module and exsl:node-set. Therefore a version of the JSON converter that does work in libxslt2 (I checked) is:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
    xmlns:func="http://exslt.org/functions"
    xmlns:str="http://exslt.org/strings"
    xmlns:js="http://muttmansion.com"
    extension-element-prefixes="func">

  <xsl:import href="http://copia.ogbuji.net/files/code/replace.xsl"/>
  <xsl:output method="text"/>

  <func:function name="js:escape">
    <xsl:param name="text"/>
    <func:result select='str:replace($text, "&apos;", "\&apos;")'/>
  </func:function>

  <xsl:template match="/">
var g_books = [
<xsl:apply-templates/>
];
  </xsl:template>

  <xsl:template match="book">
<xsl:if test="position() > 1">,</xsl:if> {
id: <xsl:value-of select="@id" />,
name: '<xsl:value-of select="js:escape(title)"/>',
first: '<xsl:value-of select="js:escape(author/first)"/>',
last: '<xsl:value-of select="js:escape(author/last)"/>',
publisher: '<xsl:value-of select="js:escape(publisher)"/>'
}
  </xsl:template>

</xsl:transform>

One more thing I wanted to mention is that there was actually a bug in 4XSLT's str:replace implementation. I missed that fact because I had actually tested a variation of the posted code that uses regex:replace. Just before I posted the entry I decided that the Regex module was overkill since the String module version would do the trick just fine. I just neglected to test that final version. I have since fixed the bug in 4Suite CVS, and you can now use either str:replace or regex:replace just fine. Just for completeness, the following is a version of the code using the latter function:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
    xmlns:func="http://exslt.org/functions"
    xmlns:regex="http://exslt.org/regular-expressions"
    xmlns:js="http://muttmansion.com"
    extension-element-prefixes="func">

  <xsl:output method="text"/>

  <func:function name="js:escape">
    <xsl:param name="text"/>
    <func:result select='regex:replace($text, "&apos;", "g", "\&apos;")'/>
  </func:function>

  <xsl:template match="/">
var g_books = [
<xsl:apply-templates/>
];
  </xsl:template>

  <xsl:template match="book">
<xsl:if test="position() > 1">,</xsl:if> {
id: <xsl:value-of select="@id" />,
name: '<xsl:value-of select="js:escape(title)"/>',
first: '<xsl:value-of select="js:escape(author/first)"/>',
last: '<xsl:value-of select="js:escape(author/last)"/>',
publisher: '<xsl:value-of select="js:escape(publisher)"/>'
}
  </xsl:template>

</xsl:transform>

[Uche Ogbuji]

via Copia

Creating JSON from XML using XSLT 1.0 + EXSLT

The article “Generate JSON from XML to use with Ajax”, by Jack D Herrington, is a useful guide to managing data in XML on the server side, and yet using JSON for AJAX transport for better performance, and other reasons. The main problem with the article is that it uses XSLT 2.0. Like most cases I've seen where people are using XSLT 2.0, there is no reason why XSLT 1.0 plus EXSLT doesn't do the trick just fine. One practical reason to prefer the EXSLT approach is that you get the support of many more XSLT processors than Saxon.

Anyway, it took me all of 10 minutes to cook up an EXSLT version of the code in the article. The following is listing 3, but the same technique works for all the XSLT examples.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
    xmlns:func="http://exslt.org/functions"
    xmlns:str="http://exslt.org/strings"
    xmlns:js="http://muttmansion.com"
    extension-element-prefixes="func">

  <xsl:output method="text" />

  <func:function name="js:escape">
    <xsl:param name="text"/>
    <func:result select='str:replace($text, "&apos;", "\&apos;")'/>
  </func:function>

  <xsl:template match="/">
var g_books = [
<xsl:apply-templates/>
];
  </xsl:template>

  <xsl:template match="book">
<xsl:if test="position() > 1">,</xsl:if> {
id: <xsl:value-of select="@id" />,
name: '<xsl:value-of select="js:escape(title)"/>',
first: '<xsl:value-of select="js:escape(author/first)"/>',
last: '<xsl:value-of select="js:escape(author/last)"/>',
publisher: '<xsl:value-of select="js:escape(publisher)"/>'
}
  </xsl:template>

</xsl:transform>

I also converted the code to a cleaner, push style from what's in the article.

[Uche Ogbuji]

via Copia

Kambili? O bia la ozo?

No, Kambili is not back, but the genius behind that wonderful character has obviously not been resting on her laurels. The buzz about Chimamanda Ngozi Adichie's sublime novel Purple Hibiscus finally compelled me to find an (alas!) rare spot in my schedule to read a novel last year. I won't soon forget the rewards. Not only does Adichie possess rare craft in prose, but her characters are vivid and sympathetic. Even the antagonist figure, Kambili's father, was rendered with the sensitivity you would expect from a seasoned storyteller. This was a first novel? Almost impossible to believe. Throw in the fact that the descriptive prose evoked so many wonderful memories of South-Eastern Nigeria, and especially of Nsukka, where I spent three years in University, engaged in a frenzy of intellectual, social, and even political activity. On a sad note she describes the terrible decomposition of the town and University of Nsukka, a process of which I've heard plenty from other Great Lions and Lionesses. I'm hardly the only one to marvel at Adichie's accomplishment. Her reviews have been effusive, and her novel won or was short-listed for an armful of awards. More importantly, it did a respectable trade, which is rare for a book of literary merit in this day. Furthermore:

Adichie’s Purple Hibiscus may soon become Nigeria’s most widely translated work after Chinua Achebe’s Things Fall Apart. The author told Sunday Sun that the book which won both the Hurston Wrights and Commonwealth Prizes and made the Orange Prize shortlist and the Booker Prize long list has been translated into nine European languages -- French, German, Lithuanian, Spanish, Italian, Greek, Polish, Dutch and of course Hebrew.

--Nigeria's Daily Sun tabloid

Imagine, then, how my ears perked up when I was listening to the Foley Flap show (a.k.a. today's All Things Considered on NPR) and I caught in a story relieving the political firestorm a reporter trying gingerly to pronounce Adichie's name. It turns out she has a new novel. It's not more from Kambili, which is in a way too bad, because Kambili is a character I hope to encounter once more. Then again every writer deserves the emancipation of their choice from their own characters, who can sometimes act as jailers. Besides, this time, Adichie has taken on quite a setting: the War for Biafra. This war is as important in the minds of most Igbos as the six-day war is in the minds of most Israelis, despite the fact that we did not enjoy the same successful outcome. (Indeed the fact that Israel was one of the only nations to support Biafra is one of the reason so many South-Eastern Nigerians have a strong pro-Israeli tendency, although some of the unfortunate recent power politics in the Middle East is beginning to test that loyalty among Igbos I know). I've read my share of novels and memoirs of those times, but as I've remarked to my father (who was an officer in the Biafran army), I think it won't be until my generation takes up the story that the episode will receive the literary and historical treatment it deserves. I'll definitely start on Half of a Yellow Sun as soon as I can, to see if Adichie is the one to prove me right.

p.s. It was fun to hear the NPR reporter pronounce "Igbo" as "Ig-boh", with the "g" and "b" clearly pronounced in separate syllables. No labial-velar plosives in the NPR pronunciation cheat-sheet, I guess.

p.p.s. I also recently bought Helen Oyeyemi's Icarus Girl, about which I've heard wonderful things. I surprise myself in the degree of possessiveness with which I eye my Nigerian middle-class peers. I'm not surprised that all the intellectual belligerence, curious creativity and dogged resourcefulness I remember from my teens is fueling a new generation of Nigerian literary accomplishment.

p.p.p.s. I also ran across an interview with Adichie in Nigeria Village Square , from which:

...religion in Nigeria has become insular, self-indulgent, self-absorbed, self-congratulatory. Churches spring up day after day while corruption thrives as much as ever and God becomes the watchman standing behind you while you seek your self-interest at all cost. God loves you more than others. God wants you to be rich. God wants you to buy that new car.

Boy did I feel that in my recent trip back home. It's rather creepy.

[Uche Ogbuji]

via Copia

Amara trimxml: an XML reporting tool

For the past few months in my day job (consulting for Sun Microsystems) I've been working on what you can call a really big (and hairy) enterprise mashup. I'm in charge of the kit that actually does the mashing-up. It's an XML pipeline that drives merging, processing and correction of data streams. There are a lot of very intricately intersecting business rules and without the ability to make very quick ad-hoc reports from arbitrary data streams, there is no way we could get it all sorted out given our aggressive deadlines.

This project benefits greatly from a side task I had sitting on my hard drive, and that I've since polished and worked into the Amara 1.1.9 release. It's a command-line tool called trimxml which is basically a reporting tool for XML. You just point it at some XML data source and give it an XSLT pattern for the bits of interest and optionally some XPath to tune the report and the display. It's designed to only read as much of the file as needed, which helps with performance. In the project I discussed above the XML files of interest range from 3-100MB.

Just to provide a taste using Ovidiu Predescu's old Docbook example, you could get the title as follows:

trimxml http://xslt-process.sourceforge.net/docbook-example.xml book/bookinfo/title

Since you know there's just one title you care about you can make sure trimxml stops looking after it finds it

trimxml -c 1 http://xslt-process.sourceforge.net/docbook-example.xml book/bookinfo/title

-c is a count of results and you can set it to other than 1, of course.

You can get all titles in the document, regardless of location:

trimxml http://xslt-process.sourceforge.net/docbook-example.xml title

Or just the titles that contain the string "DocBook":

trimxml http://xslt-process.sourceforge.net/docbook-example.xml title "contains(., 'DocBook')"

The second argument is an filtering XPath expression. Only nodes that satisfy that condition are reported.

By default each entire matching node is reported, so you get an output such as "". You can specify something different to display for each match using the -d flag. For example, to just print the first 10 characters of each title, and not the title tags themselves, use:

trimxml -d "substring(., 0, 10)" http://xslt-process.sourceforge.net/docbook-example.xml title

There are other options and features, and of course you can use the tool on local files as well as Web-based files.

In another useful development in the 4Suite/Amara world, we now have a Wiki.

With 4Suite, Amara, WSGI.xml, Bright Content and the day job I have no idea when I'll be able to get back to working on Akara, so I finally set up some Wikis for 4Suite.org. The main starting point is:

http://notes.4suite.org/

Some other useful starting points are

http://notes.4suite.org/AmaraXmlToolkit
http://notes.4suite.org/WsgiXml

As a bit of an extra anti-vandalism measure I have set the above 3 entry pages for editing only by 4Suite developers. [...] Of course you can edit and add other pages in usual Wiki fashion. You might want to start with http://notes.4suite.org/4SuiteFaq which is a collaborative addendum to the official FAQ.

[Uche Ogbuji]

via Copia

Buzzword bullying

I've lately noticed a tendency of technical folks to use "buzzword" as somewhat of a reflex epithet. We all love nudge-nudge jokes at business folks' expense, playing buzzword bingo at a particularly stultifying presentation, and the like, but I sometimes think that the practice drifts unnecessarily into serious discourse as a cheap way to shut down an opposing point.

A term is a buzzword when its use does not convey any meaning, but is meant to lend a false weight to some claim. People usually think of words and phrases such as "synergy" and "push the envelope" as buzzwords. I have almost never seen these two examples used other than as buzzwords, but certainly any regular word can become a buzzword in particular context. Words such as "value", "quality", "enterprise", "success", "architecture", "metrics" and "middleware" have their important uses, and are also sometimes used as buzzwords. I'd always thought this was simple common sense, but I've come across recent instances where I've seen anyone using these words, even in obviously meaningful ways, dismissed with the "b" word.

Certainly some suspect words are more suspicious than others, and some words have the misfortune of being popular components of buzzword phrases. "value", "success" and "business" are definitely in this category, becoming "value added", "success factors" and "business benefit", with "business value" coming off as a beacon of buzz. This does not condemn even such suspicious words to the dustbin. It's all about context. Here are a couple of words I've seen that are perfectly legitimate, but that some people seem bent on eliminating from the language (not that there is any chance in hell that they'll succeed).

  • Middleware. Used properly it stems from several computing disciplines such as model/value/controller and client/server that sought to articulate a separation of software into the part that stores and manages data, and the part that presents information to the user. Middleware is just a general term for software that is not really suited to either partition, but tends to sit in between these. It is a pretty neutral term, and you certainly don't end up notching up points for a piece of software just by calling it "middleware", so it would seem a rather poor buzzword. Then again, I have seen it used as a mumbo-jumbo term for software for which the speaker has trouble articulating a role. I think that's rare, but it would count in the buzz column.

  • Enterprise. The word simply describes a particular subset of organizations, in general ones that are closely bound by some fiduciary pressure, such as a corporation's responsibility to shareholders. The special needs of such environments does provide unique challenges to software, and thus I think "enterprise" is as often a useful distinguishing term as a mindless buzzword. A good example of a compound here is "enterprise architecture". This is a useful term that describes systems that are put together such that they work well across the departmental divisions of an enterprise, which is difficult because such divisions usually involve severe changes in focus, from research to operations to marketing to legal affairs, for example. Of course I've also seen "enterprise architecture" used by vendors as a way of saying "this is isn't your hippie open-source, Web jockey, script-and-glue technology, buddies". That definitely warrants a good scoring of the bingo card.

It's far more refreshing when debaters create and play on words rather than trying to stifle them. While I think it's silly to yell "bingo" every time someone says "enterprise", I quite approve of the snarky term "enterprisey". And anyway, I think that such tactics work a lot better than automatic buzzword bashing. I'm reading Nunberg's Talking Right: How Conservatives Turned Liberalism into a Tax-Raising, Latte-Drinking, Sushi-Eating, Volvo-Driving, New York Times-Reading, Body-Piercing, Hollywood-Loving, Left-Wing Freak Show and it strikes me that the right wing's success with setting the terms of linguistic discourse suggests that buzzword bashing is a losing tactic, anyway.

[Uche Ogbuji]

via Copia

Copia comment conundrums

Earlier this year I posted an off-hand entry about a scam call I received. I guess it soon got a plum Google spot for the query "Government grants scam" and it's been getting almost one comment a day ever since. Today I came across a comment whose author was requesting permission to use the posting and sibling comments in a book.

I have written a book on Winning Grants, titled "The Grant Authority," which includes a chapter on "Avoiding Grant Scams." It is in final stages of being (self)- published. I want to include comments and complaints about government grant scams on this Copia blog. I think the book's readers will learn alot from them.

How can I get permission to include written comments on this blog site in this book?

I'd never really thought about such a matter before. I e-mailed the correspondent permission, based on Copia's Creative Commons Attribution licensing, but considering he seemed especially interested in the comments, I started wondering. I don't have some warning on the comment form that submitted comments become copyright Copia's owners and all that, as I've seen on some sites. If I really start to think about things I also realize that our moderating comments (strictly to eliminate spam) might leave us liable for what others say. It all makes me wonder whether someone has come up with a helpful (and concise) guide to IP and tort concerns for Webloggers. Of course, I imagine such a read might leave my hair standing on end so starkly that I'd never venture near the 21st century diarist's pen again.

BTW, for a fun battle scene viewed in the cold, claret light of pedantry, inquire as to the correct plural of "conundrum".

[Uche Ogbuji]

via Copia

The Versatility of XForms

I'll be giving a presentation at the upcoming XML 2006 Conference in Boston on Tuesday December 5th at 1:30pm: The Essence of Declarative, XML-based Web Applications: XForms and XSLT.

I've been doing some hardcore XSLT/XForms development over the last 2 years or so and have come to really admire the versatility of using XSLT to generate XForms user interfaces. Using XSLT to generate XHTML from compact XML documents is a well known design pattern for seperating content from presentation. Using XSLT to generate XHTML+XForms takes this to the nth degree by seperating content from both presentation and behavior (The Model View Controller design pattern).

The icing on the cake is the XPath processing capabilities native to both XSLT and XForms. It makes for easily-managed and relatively compact applications with very little redundancy.

The presentation doesn't cover this, but the XForm framework also includes transport-level components / mechanisms that are equally revolutionary in how they tie web clients into the overall web architecture context very comprehensively (Rich Web Application Backplane has good coverage of patterns to this effect). I've always thought of XForms as a complete infrastructure for web application development and AJAX as more of an interim, scripting gimick that enables capabilities that are a small portion of what XForms has to offer.

[Uche Ogbuji]

via Copia

Rete-inspired N3 Rule Network Finished

See: previous

I called it quits (for now) in trying to retrofit the RETE-based algorithm to handle N3 functions & filters. I've checked in a rewritten Rete module with tests for SHIOF Description Logic axioms.

Tracking dependencies between filter / function variables, became hairy.

An SVG diagram of these rules compiled into a RETE-like network was generated using an included Boost Graph Library utility function.

It's unit test output:

testRules (__main__.TestEvaluateNetwork) ... Time to build production rule (RDFLib): 0.0118989944458 seconds
Time to calculate closure on working memory: 0.478726148605 seconds
ok
----------------------------------------------------------------------
Ran 1 test in 0.751s
OK

I also integrated Python iterator algebra implementation of a relational hash join (for the Beta Nodes).

It workes with RDFLib, so I'd eventually like to integrate the ability to dispatch SPARQL queries over an N3 Closure Graph - generated from the network. The speed in which it is able to render rules graphs rendered the option of serializing a compiled network into persistence a non-issue.

From the README.txt:

Fu Xi (pronounced foo-see) is a forward-chaining inferencing expert system for RDFLib Notation 3 graphs. It is named after the first mythical soveriegn of ancient china who supposedly, 'looked upward and contemplated the images in the heavens, and looked downward and contemplated the occurrences on earth.'.

Originally, it was an idea to express the formalisms of the Yi Jing / I Ching in Description & First Order Logic.

It relies on Charles Forgy's Rete algorithm for the many pattern/many object match problem - which builds a triple pattern reasoning network. It can be used as a reasoner with capabilities for certain expressive Description Logics (via OWL/RDFS axioms in N3) or a general N3 production / expert system. It uses Python hash / set / list idioms to maximize matching efficiency of the network. In particular, it uses an Iterator algebra implementation for the join activation mechanism

An example of its use:

from FuXi.Rete.Util import generateTokenSet
        from FuXi.Rete import *
        from rdflib.Graph import Graph,ReadOnlyGraphAggregate
        from rdflib import plugin
        from FuXi.Rete.RuleStore import N3RuleStore
        store = plugin.get('IOMemory',Store)()
        store.open('')
        ruleGraph = Graph(N3RuleStore())
        ruleGraph.parse(open('some-rule-file.n3'),format='n3')             
        factGraph = Graph(store)
        factGraph.parse(open('fact-file'),format='..')
        closureDeltaGraph = Graph(store)            
        network = ReteNetwork(ruleStore,
                              initialWorkingMemory=generateTokenSet(factGraph),
                              inferredTarget = closureDeltaGraph)            
        for s,p,o in network.closureGraph(factGraph):
            .. do something with triple ..

To check out from cvs:

cvs -d:pserver:anonymous@cvs.4suite.org:/var/local/cvsroot login
cvs -d:pserver:anonymous@cvs.4suite.org:/var/local/cvsroot get Fuxi

Chimezie Ogbuji

via Copia