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:
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:
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).