Python Implementation of RAX
April 26, 2000
""" RAX = Record API for XML A simple, record-oriented API for XML. Provides a simple, efficient interface for processing the sort of XML often generated from databases Sean McGrath http://www.digitome.com """ import os,sys,string class Record: """ A record drawn from an XML file is a collection of elements accessed by element type name """ def __init__(self,ElementTypeName): self.ElementTypeName = ElementTypeName self.ElementStack = [] self.Elements = {} self.CurrentChild = None self.StartChild (ElementTypeName) def GetField(self,ElementTypeName): return self.Elements[ElementTypeName] def StartChild(self,ElementTypeName): """ Start accumulating data for a new child element """ self.ElementStack.append (self.CurrentChild) self.Elements[ElementTypeName] = "" self.CurrentChild = ElementTypeName def EndChild(self,ElementTypeName): """ End accumulating data for child element. Subsequent content will be associated with enclosing element """ self.CurrentChild = self.ElementStack.pop() def AddData(self,Data): """ Associate data with currently active element """ Data = string.strip (string.replace (Data,"\\n","")) self.Elements[self.CurrentChild] = self.Elements[self.CurrentChild] + Data class RAX: """ Record API for XML - base class """ def __init__(self,fo): # Store file object from which ESIS is read self.fo = fo # Default "record" element self.RecordElementTypeName = "" def SetRecord(self,ElementTypeName): """ Set the "record" element """ self.RecordElementTypeName = ElementTypeName def ReadRecord(self): """ Read a record. """ # Skip forward to the required start-tag event line = self.fo.readline()[:-1] while line and line[1:] != self.RecordElementTypeName: line = self.fo.readline()[:-1] if not line: return None # Create a new record R = Record(line[1:]) # Trundle through accumulating info in the Record # until the end-tag event occurs line = self.fo.readline()[:-1] while line and line[1:] != self.RecordElementTypeName: if line[0] == "-": if len(line)>1: R.AddData(line[1:]) elif line[0] == "(": R.StartChild(line[1:]) elif line[0] == ")": R.EndChild(line[1:]) else: sys.stderr.write ("Unsupported Event '%s'" % line[0]) line = self.fo.readline()[:-1] return R def test(): """ Test function for RAX Process customers.xml outputting various elements """ # This code trundles through the invoices, printing # out the "from" and "to" elements. fo = os.popen ("xmln customers.xml") R = RAX(fo) R.SetRecord("Record") rec = R.ReadRecord() while rec: print "Phone=%s" % rec.GetField("Phone") rec = R.ReadRecord() if __name__ == "__main__": test()