RSS feeds for 4Suite (etc.) mailing lists

Jeremy Kloth set up RSS content feeds for Fourthought-hosted mailing lists, including the 4Suite and EXSLT lists (all on Mailman). The list information page for all the lists has an RSS link in the header, so it should be picked up by most news readers. For convenience, though, here are the main lists and the corresponding feeds:

[Uche Ogbuji]

via Copia

Dare's XLINQ examples in Amara

Dare's examples for XLINQ are interesting. They are certainly more streamlined than the usual C# and Java fare I see, but still a bit clunky compared to what I'm used to in Python. To be fair a lot of that is on the C# language, so I'd be interested in seeing what XLINK looks like from Python.NET or Boo.

The following is my translation from Dare's fragments into corresponding Amara fragments (compatible with the Amara 1.2 branch).

'1. Creating an XML document'

import amara
#Done in 2 chunks just to show the range of options
#Another way would be to start with amara.create_document
skel = '<!--XLinq Contacts XML Example--><?MyApp 123-44-4444?><contacts/>'
doc = amara.parse(skel)
doc.contacts.xml_append_fragment("""<contact>
  <name>Patrick Hines</name>
  <phone>206-555-0144</phone>
  <address>
    <street1>123 Main St</street1>
    <city>Mercer Island</city>
    <state>WA</state>
    <postal>68042</postal>
  </address>
</contact>
""")

'2. Creating an XML element in the "http://example.com" namespace'

doc.xml_create_element(u'contacts', u'http://example.com')

'3. Loading an XML element from a file'

amara.parse_path('c:\myContactList.xml')

'4. Writing out an array of Person objects as an XML file'

persons = {}
persons[u'Patrick Hines'] = [u'206-555-0144', u'425-555-0145']
persons[u'Gretchen Rivas'] = [u'206-555-0163']
doc.xml_create_element(u'contacts')
for name in persons:
    doc.contacts.xml_append_fragment('<person><name>%s</name></person>'%name)
    for phone in persons[name]:
        doc.contacts.person[-1].xml_append_fragment('<phone>%s</phone>'%phone)
print doc.xml()

'5. Print out all the element nodes that are children of the <contact> element'

for c in contact.xml_child_elements():
    print c.xml()

'6. Print all the <phone> elements that are children of the <contact> element'

for c in contact.xml_xpath(u'phone'):
    print c.xml()

'7. Adding a <phone> element as a child of the <contact> element'

contacts.xml_append_fragment('<phone>%s</phone>'%'206-555-0168')

'8. Adding a <phone> element as a sibling of another <phone> element'

mobile = contacts.xml_create_element(u'phone', content=u'206-555-0168')
first = contacts.phone
contacts.xml_insert_after(first, mobile)

'9. Adding an <address> element as a child of the <contact> element'

contacts.xml_append_fragment("""  <address>
    <street1>123 Main St</street1>
    <city>Mercer Island</city>
    <state>WA</state>
    <postal>68042</postal>
  </address>
""")

'10. Deleting all <phone> elements under a <contact> element'

for p in contact.phone: contact.xml_remove_child(p)

'11. Delete all children of the <address> element which is a child of the <contact> element'

contacts.contact.address.xml_clear()

'12. Replacing the content of the <phone> element under a <contact> element'

#Not really necessary: just showing how to clear the content
contact.phone.xml_clear()
contact.phone = u'425-555-0155'

'13. Alternate technique for replacing the content of the <phone> element under a <contact> element'

contact.phone = u'425-555-0155'

'14. Creating a contact element with attributes multiple phone number types'

#I'm sure it's clear by now how easy this would be with xml_append_fragment
#So here is the more analogous API approach
contact = contacts.xml_create_element(u'contact')
contact.xml_append(contact.xml_create_element(u'name', content=u'Patrick Hines'))
contact.xml_append(
    contact.xml_create_element(u'phone',
                               attributes={u'type': u'home'},
                               content=u'206-555-0144'))
contact.xml_append(
    contact.xml_create_element(u'phone',
                               attributes={u'type': u'work'},
                               content=u'425-555-0145'))

'15. Printing the value of the <phone> element whose type attribute has the value "home"'

print u'Home phone is:', contact.xml_xpath(u'phone[@type="home"]')

'16. Deleting the type attribute of the first <phone> element under the <contact> element'

del contact.phone.type

'17. Transforming our original <contacts> element to a new <contacts> element containing a list of <contact> elements whose children are <name> and <phoneNumbers>'

new_contacts = doc.xml_create_element(u'contacts')
for c in doc.contacts.contact:
    new_contacts.xml_append_fragment('''<contact>
    <name>%s</name>
    <phoneNumbers/>
    </contact>'''%c.name)
    for p in c.phone:
        new_contacts.phoneNumbers.xml_append(p)

'18. Retrieving the names of all the contacts from Washington, sorted alphabetically '

wash_contacts = contacts.xml_xpath(u'contact[address/state="WA"]')
names = [ unicode(c.name) for c in contacts.contact ]
names.sort()

[Uche Ogbuji]

via Copia

"XML in Firefox 1.5" pubbed

"XML in Firefox 1.5"

The open source Firefox Web browser continues to grow in popularity. Users like the security and convenience features it offers. Developers like the Firefox attention to standards compliance, inherited from its Mozilla roots. The most recent version, Firefox 1.5, comes with many features for XML developers, including XML parsing, XHTML, CSS, XSLT, SVG, XML Events in JavaScript™, and XForms. Additional third-party extensions provide even more XML support. In this article, Uche Ogbuji provides an overview of XML features in Firefox 1.5.

I wrote this article before the recent Firefox 1.5beta1 release, but I don't think that release has led any of the points in the piece to be outdated.

Thanks to Kurt Cagle, for his technical review of the article.

[Uche Ogbuji]

via Copia

Triclops - Resurrected

Like a pheonix from the flames, I've resurrected an old RDF querying interface called Triclops. It used to be coupled with the 4Suite repository's defunct Dashboard (which I've also tried to resurrect as an XForms interface to a live 4Suite repository - there is more to come on that front, thanks to FormFaces) but I've broken it out into it's own stand alone application. It's driven by this stylesheet which makes use of two XSLT extensions (http://metacognition.info/extensions/remote-query.dd#query and http://metacognition.info/extensions/remote-query.dd#graph) both of which are defined here.

I've updated the tabled,triple result page to include ways to navigate graphs by clicking on subjects (which takes you to a subsequent triple result page for that particular subject), predicates (which takes you to another triple result page with statements which use that predicate), and objects (which allows you to jump from graph to graph along rdfs:seeAlso / rdfs:isDefinedBy relationships). Note that it assumes the objects of rdfs:seeAlso and rdfs:isDefined by are live URIs that return an RDF graph (the most common use for these is for FOAF networks and relationships between ontologies).

I've also included buttons for common, 'canned' queries that can be executed on any graph, such as:

  • All classes: type(list(rdfs:Class,owl:Class))
  • rss:items: type(rss:item)
  • Dated Resources: all()|-dc:date->*
  • Today's Items: all()|-dc:date->contains(.,".. today's date ..")
  • Annotated Resources: all()|-list(rdfs:label,rdfs:comment,dc:title,dc:description,rss:title,rss:description)->*
  • Ontologies: type(owl:Ontology)
  • People: type(foaf:Person)
  • Everything: all()

In addition, I've added some documentation

P.S.: The nodes in the RDF diagrams generated by Triclops (as an alternative to raw triples) are live links. The JPEG diagrams are associated with image maps (generated by graphviz) that allow you to click on the nodes and the SVG diagrams are rendered with links as well (depending on the level of maturity of your SVG viewer - this might or might not be the prefered diagram format). The SVG diagrams have alot potential for things such as styling and the other possibilities that are standard to SVG.

In all, I think it provides a very user-friendly way to quickly traverse, whittle, and circumnavigate the "Semantic Web" - whoops, there is that phrase again :)

4Suite Repository and 4Suite RDF have become sort of bastard children of recent 4Suite development and I've been focusing my efforts lately in moving the latter along - The former (the Repository) only lacks documentation IMHO as Metacognition is run entirely as a 4Suite Repository instance.

Chimezie Ogbuji

via Copia

Solution: simple XML output "templates" for Amara

A few months ago in "Sane template-like output for Amara" I discussed ideas for making the Amara output API a little bit more competitive with full-blown templating systems such as XSLT, without adopting all the madness of template frameworks.

I just checked in the simplest patch that does the trick. Here is an example from the previous article:

Amara 1.0 code:

person_elem = newdoc.xml_element(
        u'person',
        attributes={u'name': unicode(person.name)}
    )
newdoc.xml_append(person_elem)

Proposed Amara 1.2 code:

newdoc.xml_append_template("<person name='{person.name}'/>")

What I actually checked into CVS today for Amara 1.2:

newdoc.xml_append_fragment("<person name='%s'/>"%person.name)

That has the advantage of leaning as much as possible on an existing Python concept (formatted strings). As the method name indicates, this is conceptually no longer a template, but rather a fragment of XML in text form. The magic for Amara is in allowing one to dynamically create XML objects from such fragments. I think this is a unique capability (shared with 4Suite's MarkupWriter) for Python XML output APIs (I have no doubt you'll let me know if I'm wrong).

Also, I think the approach I settled on is best in light of the three "things to ponder" from the older article.

  • Security. Again I'm leaning on a well-known facility of Python, and not introducing any new holes. The original proposal would have opened up possible issues with tainted strings in the template expressions.
  • String or Unicode? I went with strings for the fragments. It's up to the developer to make sure that however he constructs the XML fragment, the result is a plain string and not a Unicode object.
  • separation of model and presentation. There is a very clear separation between Python operations to build a string XML fragment (these are usually the data model objects), and any transforms applied to the resulting XML binding objects (this is usually the separate presentation side). Sure a determined developer can write spaghetti, but I think that with xml_append_fragment it's possible and natural to have a clean separation. With most template systems, this is very hard to achieve.

One other thing to mention is that the dynamic incorporation of the new fragment into the XML binding makes this a potential building block for pipelined processing architecture.

def process_link(body, href, content):
    body.xml_append_fragment('%s'%(href, content))
    #Send the "a" element object that was just appended to
    #the next pipeline stage
    check_unique(body.a[-1])
    return

def check_unique(a_node):
    if not a_node.href in g_link_dict:
        #index the href to the link text (a element text content)
        g_link_dict[a_node.href] = unicode(a_node)
    return

[Uche Ogbuji]

via Copia

On Huck, Hip Hop, and Expression

"I was born where the weather's forever warm,
   ... except for the storms ...
   Dirty south! Baby, It's sketched on my arm,
   Till' death and beyond,
   Country like I'm living next to a farm
   and war, like we resurrected from 'Nam
   I get it from Mom.
   Short-tempered, weapon in palm,
   Like Malcom X, we study Techs instead of Koran
   Who said it was calm?!
   We're like the Palestinians and Jews, except for the bombs,
   That's why I must address it in song ... "

This is my ode to Hip-Hop and a chance to share a little bit about the lesser known of the three Ogbuji brothers. Above is my favorite quote of his from a song (“Life Begets Evil”) within an a body of work we spent quite some timeon, called "Ahead of My Time." His musical alias is Huck Finn (same as the character in Mark Twain's work). That garage band site, is where I plan to host a few songs from the album. We worked on it over the winter of 2002, during one of the low points in my life (don't let the smile in that photo fool ya) where I was destitute, boarding with my parents, without employment, and seriously considering (with the state of the economy and all) that I had picked the wrong profession and needed to seek other passions in life.

It was a scattered collection of his thoughts and (in his words basically), the culmination of a 7 year effort to master the art of MCing (moving the crowd - as KRS One puts it). I've often asked Ejike if he has done any significant work since 'Ahead of My Time' and he says he hasn't mostly because as far as he's concerned it was the most complete representation / expression of himself and any further creative attempt would do it a disservice. I can't argue with that because in its essence that's what Hip Hop is, ultimately: a powerful form of expression.

So, I've made a promise to him that some day I'll find the means to get the original work professionally mastered (originally, he recorded the tracks and produced the instrumentals with his microphone and Fruity Loops, while I mixed and mastered them with Acid Pro 4.0), design the cover with the original art we decided on, shrink-wrap it and do some grass roots marketing. I intend to keep my promise someday.

This is my favorite quote because it's a direct reference to a past time in 1997 when he, myself and my two best friends Nnedi Okorafor and Okechukwu Mbachu decided to embark on a road trip to New Orleans. It was there that he and I got tatoos - for different reasons. He got a tatoo that said 'Dirty South Swamp Land' (on his left arm) and I got a tatoo that said 'Umunne Kwenu' (on my upper-forearm). I won't go into the whole politics of tatoos and why some despise them and others abuse them (in my mind), but I mention it because his reference to it is one of the reasons why the above quote resonates with me. In addition, his reference to his birthplace, Gainsville Florida (“where the weather is forever warm – except for the storms”) makes it further hit home, but the icing on the cake is the reference to our mother and her short temper (one which only her sons have been privileged to experience) but few realize exists.

I'm digressing a bit, because as much as I wanted to write about Ejike, I mainly wanted to try to express my love for the art form he tried so hard (and so successfully, IMHO) to perfect: Hip Hop and MCing.

I was inspired to write this when I recently heard Ice Cube on NPR's 'Fresh Air' and the interview almost brought me to tears. Why? When asked why Hip Hop shouldn't be considered a bad influence for the younger generation and in general, he responded that Hip Hop is about expression and about Ego. He said, for him, it was a healthy way to find a voice to express himself in the very turbulent world he found himself in. I was moved, because in only a few concise sentences, the man (whom my experience with the artform began) completely articulated the essence of the artform. Unfortunately, transcripts are not freely available, but can be purchased

You see, when Uche, Ejike, and I were reunited back in 1989 (in East Brunswick, NJ), he had us listen to NWA's album (which marked the beginning of the second renaissance of Hip Hop – the first was triggered by Whodinis Rappers Delight). We stood there, not even teenagers, hit first by the language, but what stuck with us was the powerful expression.

It stayed with all three of us and effected us differently, but it definitely had a permanent effect on us. I tell people all the time that Hip Hop saved my life in High School, and they think I'm overstating the truth, but I'm not. Highschool was a period in my life where the effect of cultural transplantation had a devastating effect of my sense of self worth and identity. I stood out like a sore thumb, visually, culturally, and phonetically. However, in Hip Hop, I found a medium of expression that helped emphasized my individuality and a healthy ego.

There is something about a rhythmic percussion and base, steady vocal cadence, and gritty imagery – peppered with uncensored dialect that simply get's the hair on the back of my head to stand straight up. I swear, every time I hear Cannibus' (By far my favorite MC) Master Thesis, I get a chill and rewind at least 3-4 times. Why?

Well, I'm not a Christian, but when my rel:lifePartnerOf explained to me the denominational distinctions (within the Christian faith) in whta constitutes the act of speaking in tongues, I felt it was the perfect analogy. As I understand it, one thing that is common to all (or at least most) denominations is that the Holy Spirit resides inside all of us and can manifest itself in a variety of ways – the most prominent being the ability to channel through its host, verbally. I think of the act of MCing (onced honed) as similar. Whereas one is spontaneous, the other takes hard work.

Very hard work. Ejike would spend days on end in the summers, writing in piles of lined notebooks, working on his cadence, delivery, content, intensity. The most useful tool for this (and this is the same for most other MCs) is freestyling. The concept is well known from the movie 8 Mile, but when you are at the point where you can channel your thoughts and the images that resonate with you directly without much thought for perfecting the delivery or how you may seem to those observing, it's a similar phenomenon. The main difference is that whereas when speaking in tongues the origin is the Holy Spirit, in Hip Hop the origin is the unfiltered combination of ego and self expression. In fact, this analogy is very striking and perhaps not completely coincidental considering the cultural context in which both forms flourish is one and the same.

I've done my own share of honing, and I'm much better than I used to be – no where as good as Ejike, but there is some satisfaction in knowing that if I ever were to come across a Cipher – a group of amateur MC's practicing their delivery with each other – I could hold my own. I would leave feeling like I've connected with people I may not have known or will ever know again through a dialect that's somewhat based on a musical artform, but fused mostly with that part of me that is most unique.

Someday, I'll finish what Ejike and I started in the winter of 2002 and come through on my promise to him to put the finishing touches on the culmination on his effort to master an artform that effected him as much as it did his other two brothers. If not for him, then at least in honor of the artform itself and it's immeasurable value as a means to carve out my identity in a multi-cultural society - one which is but a microcosm of the infinite variety that is our existence on this lonely, rotating sphere.

[Chimezie Ogbuji]

via Copia

Nofollow-free Copia

I read this interesting post by Darryl VanDorp:

Hey people new to this whole blog thing. If you want me to actually leave a comment on that new blog of yours. Turn off that damn default nofollow in your shiny wordpress installation ... If I take the time to leave a comment give me some juice!

I quite agree. Yes, I know nofollow came about as a way to discourage Weblog spammers, but I don't believe it will ever work. It is just too easy to write robots that leave comment spam, and unless 100% of systems use nofollow, which is never likely, it will always be worth the spammers' while to keep trying on the off chance that they find sites without nofollow. Also, spammers are probably happy to have their messages on Weblogs, google juice or no.

Look, we don't want comment spam on Copia, period. It's not enough to deprive them of google juice. We work to keep the site spam-free. All comments go in an approval queue, and we have a lot of handy little tools to help eliminate comment spam, so we can batch approve the remaining goodness. I think this takes a lot less effort than the actual work of composing entries on the blog (and I'm a fast writer). What's more relevant, it's less effort than it takes for visitors to compose their comments. As a result of this effort there is no need to use nofollow on Copia, and we don't do so. I don't know whether commenters get significant juice from Copia, but what juice we do have to give we shall not stint our correspondents. (Not even if they are here to engage in the heresy of disputing our positions.)

I can't help thinking of the gardening analogy. If you want a nice garden, you have to roll up your sleeves and pull up your weeds. There is no quick fix to preventing weeds: the conditions that make your soil attractive for germination of desirable flowers also make it attractive to Uncle Darwin's rogues.

[Uche Ogbuji]

via Copia

Today's XML WTF

via Sam Ruby:

While [REXML] is certainly the most elegant Ruby XML API, it seems to accept a variety of ill-formed XML fragments, for example the following produces no error: [<div>at&t]

F'real? That is, not only missing end tag, but also unescaped ampersand?

It is just not frigging cool to be releasing anything called an XML parser or processor in 2005 that does not reject ill-formed XML. Folks, well-formedness is the entire point of XML. If that's an inconvenient fact for you, please be so kind as to use something other than XML. What is even more galling is this from the REXML home page:

REXML is an XML processor for the language Ruby. REXML is conformant (passes 100% of the Oasis non-validating tests), and includes full XPath support.

On Sam's evidence (and you don't get much more credible than Sam Ruby), this statement is quite false. The OASIS XML 1.0 tests have a whole section covering rejection of non-well-formed documents.

Sam goes on to say:

Peeking into the implementation of REXML, I see that it is riddled with regular expressions. Having a parser that doesn’t detect errors properly is one thing, but having a parser that incorrectly parses valid input is quite another. I’ve opened a ticket on one such problem.  Depending on how it is received, I may open others.

OK. Let's hope the REXML folks pay attention to Sam and get things right.

And before Python folks get all smug, it seems that such fast and loose interpretations of what "XML" means is hardly alien to the Python community. Here's a thread on the XML-SIG with a "list of packages handling XML 1.1". Any sensible person would expect these to be XML 1.1 parsers, but no, it turns out that the title is a bit of casuistry, and that at least 2 of the 4 listed packages accept ill-formed XML 1.1. It seems to me that pyparsing, Python's re library, Python's string methods, and any other Python software that does anything with strings should be added to such a list. The only way I could imagine such a list being redeemed is if entries that did not accept well-formed XML 1.1 at least offered warnings of ill-formedness, and could thus serve as tidy-like tools for fixing broken XML. This does not seem to be the case.

As I've said in the past, I don't claim that only XML parsers and processors should be used to work with XML. Heck, I use grep, wc, sed and the usual text tools all the time with XML documents. I do say that it is dishonest to call something an XML parser or processor unless you treat non-compliance as a bug. I guess it's the old social principle all over again. XML is hot, so it's voguish to be called an XML processor, yet it's all so tempting to shirk the required work.

[Uche Ogbuji]

via Copia

XHTML tutorial pubbed

"XHTML, step-by-step"

Start working with Extensible Hypertext Markup Language. In this tutorial, author Uche Ogbuji shows you how to use XHTML in practical Web sites.

Get started working with Extensible Hypertext Markup Language. XHTML is a language based on HTML, but expressed in well-formed XML. But XHTML is much more than just regularizing tags and characters -- XHTML can alter the way you approach Web design. This tutorial gives step-by-step instruction for developers familiar with HTML who want to learn how to use XHTML in practical Web sites.

In this tutorial

  • Tutorial introduction
  • Anatomy of an XHTML Web page
  • Understand the ground rules
  • Replace common HTML idioms
  • Some practical considerations
  • Wrap up

[Uche Ogbuji]

via Copia