CS 2340 Spring 2007

 

Saving Objects:

 

When I originally tried to save objects using BOSS, it wouldn't let me because the object I was trying to save had incorporated visual parts into it (i.e. It had a circle or a line reference inside of it). The solution I used was to take the attributes out of the object, saved them, then when I loaded I just made a new object and set the attributes to that object. Here are the steps to do this:

 

  1. Create an XML.Document
  2. Send the XML.Document the addNode message and put in the XML.Tag you would like to name the attribute you want to save.
  3. Send that node the addNode message and put in the XML.Text you want to save.
  4. Repeat 2 and 3 as needed.
  5. Give it a filename, write it out and make sure it closes

 

For example, to save an light-bulb object that knows how to draw itself, you probably only need to save the number of hours it has been running. Here is some sample code to do that:

 

|newDoc str writer|

saveBulb: lightBulb name: fileName

newDoc := XML.Document new.

newDoc addNode: (XML.Element tag: 'xml').

newDoc root addNode: ((XML.Element tag: 'lightBulb')

            addNode: ((XML.Element tag: 'hours')

                                   addNode: (XML.Text text: lightBulb hours));

str := fileName asFilename writeStream.

writer := XML.SAXWriter new output: str.

[newDoc saxDo: writer] ensure: [str close].

 

This code will save a file that looks like this

 

fileName

---------------------------------------------------------------

|<xml>                                                                        |

|           <lightBulb>                                                     |

|                       <hours>                                              |

|                                   80                                           |

|                       <hours>                                              |

|           <lightBulb>                                                     |

|</xml>                                                                       |

---------------------------------------------------------------

 

If you did it correctly, you can open it in Internet Explorer and it will have little plus boxes on the left so you can tree view it.

 

It is important to note that the fileName you send it can include an extension if you like so you could name it “lightBulb” or “LightBulbs.xml” or “temp.a” or whatever you want. The filename also works as either a relative path or an absolute path. So you can save to “C:\temp\LightBulbs.xml” or just “LightBulbs.xml.” The later of the two will save the file to your image directory. 

 

It's also important to put everything inside xml tags because the parser won't work quite correctly otherwise.

 

Let's say we named the file “LightBulbs.xml” and we want to now load it. Well, to load the file you do the following sets:

 

  1. Create an XML.XMLParser object.
  2. Give it the fileName of the file you want to parse.
  3. Make a new object you want to become your loaded object.
  4. Parse the file and put the attributes into the new object you just made.
  5. Return the object.

 

Here is some sample code to do this:

 

|ocLightBulbs lightBulb parser pdoc tempHours|

            parser := XML.XMLParser new.

            parser validate: false.

            pdoc := parser parse: fileName.

            ocLightBulbs := OrderedCollection new.

            pdoc root elementsNamed: 'lightBulb' do:[: e|

                        tempHours := e elementsNamed: 'hours'.

                        tempHours := ((( tempHours at: 1) elements at: 1) characterData).

                        lightBulb := LightBulb new.

                        LightBulb hours: tempHours asNumber.

                        ocLightBulbs add: lightBulb.

            ].         

            ^ocLightBulbs

 

 

The third line about setting the validate to false is important because if you do not, you will have to add alot of mess to the XML saving function to make this pass. The 6th line “pdoc root elements Named: 'lightBulb' returns an ordered collection of all the elements in the document named lightBulb (i.e. Everything in the document enclosed in <lightBulb> ... </lightBulb>). The look just strips the hours element out and puts it into tempHours. Since we only have one lightBulb int the xml file, the ordered collection isn't really necessary for this example but the point is you could have several lightbulbs in the xml file or none. Also, be sure to convert your data type to whatever your object holds (i.e. On the line “LightBulb hours: tempHours as Number,” assuming hours is a number, it wouldn't work if we just tried to put a characterData into it).