Eek XML Code Snippets
Eek XML Code Snippets
PHP5 has XML support built right into the language, somewhat similar to my Eek plan. Unfortunately, like so many other XML APIs, their namespace support is horrible. This makes the API useless, since all W3C Standards are built on namespaces and it's hard to do any serious XML work without them.
Here is an overview over PHP5's XML capabilities. They have a couple of examples, and I try to port them to Eek's hypothetical XML API. Note that their first example shows PHP4's DOM API as a bad example, and I start at their second. Because Eek does not allow stand-alone code and I have no idea how to load an XML document yet, they will get the document as method argument instead of loading it using 'simplexml_load_file()'. So here is the first example, ported to Eek:
class EekXMLTest1
processLibrary(<:library> library)
for <:shelf> shelf in library..shelf
Console.println("Shelf {shelf.@id}")
for <:book> book in shelf..book
Console.println("Title: {book..title}")
Console.println("Author: {book..author}")
end
The notation '<:library>' looks quite unusual, but it is just a convenience form of 'Element<:library>'. It declares an XML Element with ':library' as first class parameter. ':library' is a QName literal with the default namespace that specifies what kind of elements are allowed - only the '<library>' element is.
'..' is the operator to access all elements with the name given as QName argument. So 'library..shelf' takes the Element 'library' and returns a list of all 'shelf' elements that it contains. The formal type of the returned list is 'ElementList<:shelf>'. Note that there is a special exception that allows the ommision of the colon (':') between the operator '..' and the QName.
'.@' is used to access attributes, so 'shelf.@id' returns the content of the '.@id' attribute.
Here's the second example, with namespaces (the 4th example in the text, as the third is another bad example):
namespace blog "http://www.edwardbear.org/serendipity/"
class EekXMLTest2
processEntries(<:entries> entries)
for <blog:entry> entry in entries
Console.println("{entry..blog:name}")
end
The most important thing is the 'namespace' declaration in the first line. It declares the identifier 'blog' to be a namespace. The prefix can then be used for QNames and in XML literals. The type '<blog:entry>' is a short form of 'Element<blog:entry>', an element which is guaranteed to be in the namespace defined by 'blog' and to have the local name 'entry'. The expression 'entry..blog:name' also uses the 'blog' namespace to access the 'blog:name' element.
One last word about the 4th PHP example: the PHP example is already complicated, but it actually has two additional problems: it does not check whether the children of '<entries>' are actually '<entry>' elements, and it does not check the namespace of the '<blog:entry>' element. In a clean example it would be easier to see how bad the PHP syntax is for namespaces.
written at 00:37. (0 Comments, Permalink)