0

I am trying to implement SAX parser in python. Reading the XML and creating objects. Below is my code.

import xml.sax

class Employee :
    def __init__(self, id):
        self.id = id


class EmployeeHandler(xml.sax.ContentHandler):

    emp = None
    emplist = []
    fName = False
    lName = False
    age = False
    company = False

    def __init__(self):
        xml.sax.ContentHandler.__init__(self)

    def startElement(self, name, attrs):
        print("startElement '" + name + "'")

        if name == "Employees" :
            global emplist
            emplist = []

        if name == "Employee":
            global emp
            emp = Employee(attrs.getValue("id"))
        elif name == "FirstName":
            global fName
            fName = True
        elif name == "LastName":
            global lName
            lName = True
        elif name == "Age":
            global age
            age = True
        elif name == "Company":
            global company
            company = True

    def characters(self, content):
        print("characters '" + content + "'")
        global fName, lName, age, company
        if fName is True:
            emp.firstName = content
        elif lName is True:
            emp.lastName = content
        elif age is True:
            emp.age = content
        elif company is True:
            emp.company = content



    def endElement(self, name):
        print("endElement '" + name + "'")
        if name == "Employee":
            #global emplist : To use list methods global is not required
            emplist.append(emp)


def main(sourceFileName):
    source = open(sourceFileName)
    xml.sax.parse(source, EmployeeHandler())


if __name__ == "__main__":
    main("EmployeeData")
    print("Ids ", emplist[0].id , emplist[1].id)

While executing the code I am getting the below error :

 File "C:/Users/611834094/PycharmProjects/PractiseProject/xml_pratise/saxparser.py", line 47, in characters
    if fName is True:
NameError: name 'fName' is not defined

To be precise the below block is raising the error :

def characters(self, content):
    print("characters '" + content + "'")
    global fName, lName, age, company
    if fName is True:
        emp.firstName = content

The variable fName (along with other global variables) are defined with an initial value which is getting changed in the startElement() method of the handler, in the characters method, I am trying to compare the value of fName against True (boolean), I am getting the error as mentioned above.

Thank you

Vasilis G.
  • 7,556
  • 4
  • 19
  • 29
setu shwetank
  • 93
  • 1
  • 7
  • [Why are global variables evil](https://stackoverflow.com/questions/19158339/why-are-global-variables-evil). – Georgy Feb 10 '18 at 13:18
  • Those variables don’t exist as global variables. They are *class attributes*. – But they should really be instance members instead. – poke Feb 10 '18 at 14:13

2 Answers2

0

The reason this does not work is that you don't have any global variables defined. Instead you have class members defined, which are not globally scoped, but scoped in the object. These can be accessed through the self parameter, which is the class instance:

if self.fName:
    self.emp.firstName = content

etc

Jesse Bakker
  • 2,403
  • 13
  • 25
  • Thanks for response Jesse. If you I have declared following global variables .emp = None emplist = [] fName = False lName = False age = False company = False in class EmployeeHandler , changing the value in startElemen() methods and comparing in characters() method. – setu shwetank Feb 10 '18 at 13:40
0

I'll just take some fragments of your code:

class EmployeeHandler(xml.sax.ContentHandler):

    ....
    fName = False
    ....
      elif name == "FirstName":
            global fName
            fName = True
     ....
         global fName, lName, age, company
         if fName is True:

The global keyword makes fName to be global outside the class. To use the class variable fName you should prefix it with the class name:

      elif name == "FirstName":
            EmployeeHandler.fName = True
      ....
            if EmployeeHandler.fName is True:

Having said that, none of those variables appear to be suitable as class variables, it would seem that they should actually be object instance variables, i.e. attached to self as described by @JesseBakker. They appear to be properties of each single Employee, not to the whole class.

cdarke
  • 42,728
  • 8
  • 80
  • 84