XML.com: XML From the Inside Out
oreilly.comSafari Bookshelf.Conferences.

advertisement

RAX: An XML Database API
by Sean McGrath | Pages: 1, 2

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