2007-09-30 19:40Pidgin XML processingI recently had cause to make use of a language I had enjoyed messing around with before, namely XSLT. Unfortunately that language still hasn’t reached the critical mass of having strong support in IDEs, active user communities, and clear documentation, for which it seems some of the blame lies with the overly-abstracting, purely academic viewpoint of some people in their ivory towers that no longer seem to be solving the real problems that exist. Instead of a coherent view for XML technologies forming and being adopted, there is a rush to generate more and more over-arching, under-supported, paper-tiger standards, with the community expected to bounce between them and fill in the gaps while finding extremely niche or unnecessary use cases to justify their existence. The experts even accept there are problems with the core of XML itself, but how many people do they think are making use of, or even know about, things like XSL-FO, XPath, XQuery, XLink, XPointer, OWL, RDF, SPARQL, Turtle, N-Triples, Notation 3, and SKOS? It is therefore not without reservation that I delve into this world with XSLT, but it did seem like the right tool for the job and a rather fun logic puzzle. Statement of the problemAfter making a new friend recently, and wanting to find a loophole in my rules which instituted a moratorium on adding people to my instant messaging contact list, I decided I could start talking to this person using Pidgin as long as we used an open protocol. The simplest way to do this seemed to be for me to sign up for a Jabber account on an independently run server and for my friend to sign up for a Google Talk account and use the official client. I had been planning to do this for a while, as some of the other acquaintances on my contact list had Jabber compatible accounts too, and the more contacts that use open protocols, the less I would be affected by a closed protocol introducing some incompatibility or having all their servers go offline. So the particular situation arose where I had added Jabber contact details for some people with whom I had been using ICQ to chat in the past, and I wasn’t sure whether I still needed to have an ICQ account any more. How could I find out? One might argue that the recent controversial change to the Pidgin interface would make that more difficult, because it hides (or “abstracts away”) the detail of which protocol(s) a given buddy uses. I find that change generally positive, however, and even before the change it was difficult to get a definitive answer of whether you needed a given protocol any more because the contact list would by default only show one of the protocols available for a given contact. (There is of course the other controversial UI change to Pidgin which I was less happy about, until I read the advice about options you could change to select a more usable window layout). So, whether old or new or customised interface, a manual search through all your online and offline contacts to see whether they only had ICQ accounts seemed excessively onerous and error prone. If only someone had invented a device which could process information according to instructions given to it by a human operator… Solving the problem… Wait! I have one of those! It’s called a computer! Of course, the information in question is the buddy list, which is fortunately available as a single file, in your home directory on Linux, and the instructions given have to be in a form which is suited to the data. The reason I chose XSLT then is because the single file is an XML file, blist.xml. Looking at it showed that it consisted largely of The precise information I wanted to know, though, was not which buddies used ICQ, but which buddies used ICQ and no other protocol (although admittedly this method doesn’t deal with people for whom I have contact details relating to a non-ICQ protocol but who now only use ICQ). I found that one way of expressing this condition was to test that <xsl:if test="count(buddy[@proto = ‘prpl-icq’]) != 0"> <xsl:if test="count(buddy[@proto != ‘prpl-icq’]) = 0"> … </xsl:if> </xsl:if> using a nested The resulting full XSL was thus: <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <ol> <xsl:for-each select="purple/blist/group/contact"> <xsl:if test="count(buddy[@proto = ‘prpl-icq’]) != 0"> <xsl:if test="count(buddy[@proto != ‘prpl-icq’]) = 0"> <li> <p>Alias: <xsl:value-of select="buddy/alias"/></p> <p>Name: <xsl:value-of select="buddy/name"/></p> <p>Servernick: <xsl:value-of select="buddy/setting[@name=’servernick’]"/></p> </li> </xsl:if> </xsl:if> </xsl:for-each> </ol> </xsl:template> </xsl:stylesheet> ResultThen there was just the simple matter of applying this transform to (a copy of) the contact list file (just in case). For that I used the handy tool XMLStarlet, having found KXSLDbg to be difficult, ineffective and in serious need of a usability review — why should you have to specify an output file before you are able to use the “Goto XPath” feature, why are the boxes for specifying files greyed out, why is “Configure” under “Debug” and not under “Settings”, …? XMLStarlet was quite reasonable for a command line program, and the error messages it gave me did provide some help in understanding what I was doing wrong. The invocation I used was xmlstarlet tr transform.xsl blist.xml | tidy -asxhtml -indent -quiet -wrap 120 -f /dev/null which uses the HTML Tidy program to pretty-print the output and make it valid XHTML. The extra arguments to that command stop it from arbitrarily cutting your lines at 68 characters wide and send all the error messages to /dev/null where they are ignored. The final output looks something like this: <?xml version="1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content="HTML Tidy for Linux/x86 (vers 1 September 2005), see www.w3.org" /> <title></title> </head> <body> <ol> <li> <p>Alias:</p> <p>Name: 123456789</p> <p>Servernick: SomeBuddy</p> </li> <!— More list elements here —> </ol> </body> </html> Is there a templating language out there which is a cross between XSL and PHP, so you can have: …
<p>There were <echo>$count</echo> results found. <if condition="$count==0"><span class="warning">Warning: No results found means the data has been stolen!</span></if></p> … ? Trackbacks
Trackback specific URI for this entry
No Trackbacks
Comments
Display comments as
(Linear | Threaded)
XSLT is very powerful and in the integration space we use it all the time, but although it can concisely solve problems it's very hard to understand.
For example I believe the below should do the same thing, in one line but... it aint nice.
....
XSLT is very powerful and in the integration space we use it all the time, but although it can concisely solve problems it's very hard to understand.
For example I believe the below should do the same thing, in one line but... it aint nice.
<xsl:for-each select="purple/blist/group/contact[buddy[@proto = 'prpl-icq']][not( buddy[@proto != 'prpl-icq'])]">
....
</xsl:for-each>
|
QuicksearchCategoriesSyndicate This BlogBlog Administration |