Menu

Python Implementation of RAX

April 26, 2000

Sean McGrath and Rohit Khare

(Download Python source)


"""

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()