| Throughout this document, I've been talking about parsing XML documents into Python objects. I have yet to mention using Python objects to output XML. The reason for this rather glaring omission is that neither XMLObject nor XMLObjApp contribute to the process. I've tried to figure out a way to automate code generation to output XML, but it is much harder to come up with a generic solution than you might suppose. So instead of creating some code destined to be eternally buggy, I've decided to reserve this portion of the documentation to illustrate how you can write your own code members to output XML. Let's parse our earlier addressbook example with a simpler parser. Example 4.3. Addressbook and Simpler Parser <AddressBook> <User ID="1"> <Nickname>Gre7g</Nickname> <Email>gre7g@wolfhome.com</Email> <Address>2235 West Sunnyside Dr.</Address> <City>Cedar City</City> <State>MT</State> <Zip>74720</Zip> </User> <User ID="2"> <Nickname>Jimbo</Nickname> <BestFriend ID="1" /> <Email>jimbo@hotmail.com</Email> <Address>115 North Main</Address> <Address>Apartment #309</Address> <City>Columbia</City> <State>MO</State> <Zip>65201</Zip> </User> </AddressBook> # vvv Generated code, do not modify vvv import XMLObject # ^^^ Generated code, do not modify ^^^ # vvv Generated code, do not modify vvv class Text: ChildSpec = XMLObject.ChildClass({"#PCDATA": XMLObject.PCDATAChild("Strip", "Text")}, "#PCDATA") def __init__(self, XMLStack=XMLObject.Stack()): self.Text = "" # ^^^ Generated code, do not modify ^^^ # vvv Generated code, do not modify vvv class BestFriend: ChildSpec = XMLObject.ChildClass({}, "") def __init__(self, ID, XMLStack=XMLObject.Stack()): self.ID = XMLStack.ReferenceID(ID, XMLStack) # ^^^ Generated code, do not modify ^^^ # vvv Generated code, do not modify vvv class User: ChildSpec = XMLObject.ChildClass({"Nickname": XMLObject.StdChild(Text, "Nickname", "Single", Reduce="Text"), "Email": XMLObject.StdChild( Text, "Email", "Single", Reduce="Text"), "Address": XMLObject.StdChild( Text, "Address", "List", Reduce="Text"), "City": XMLObject.StdChild( Text, "City", "Single", Reduce="Text"), "State": XMLObject.StdChild( Text, "State", "Single", Reduce="Text"), "Zip": XMLObject.StdChild( Text, "Zip", "Single", Reduce="Text"), "BestFriend": XMLObject.StdChild (BestFriend, "BestFriend", "Single", Reduce="ID")}, "(<Nickname>)?(<BestFriend>)?(<Email>)?(<Address>)*(<City>)?(<State>)?(<Zip>)?" ) def __init__(self, ID, XMLStack=XMLObject.Stack()): self.ID = XMLStack.UniqueID("User", ID, self, XMLStack) self.Nickname = "" self.Email = "" self.Address = [] self.City = "" self.State = "" self.Zip = "" self.BestFriend = "" # ^^^ Generated code, do not modify ^^^ # vvv Generated code, do not modify vvv class AddressBook: ChildSpec = XMLObject.ChildClass({"User": XMLObject.StdChild(User, "User", "Dict", Key="ID")}, "(<User>)*") def __init__(self, XMLStack=XMLObject.Stack()): self.User = {} # ^^^ Generated code, do not modify ^^^ To output XML, we will need to add a member function to both the AddressBook and User classes. There isn't much point in adding code to either the BestFriend or Text classes because all instances of these classes will be reduced. There will not actually be any instances of these classes in the final, parsed object hierarchy. You can use most any member function name to output XML, but I prefer __repr__: Example 4.4. AddressBook Parser with __repr__ Additions # vvv Generated code, do not modify vvv import XMLObject # ^^^ Generated code, do not modify ^^^ # vvv Generated code, do not modify vvv class Text: ChildSpec = XMLObject.ChildClass({"#PCDATA": XMLObject.PCDATAChild("Strip", "Text")}, "#PCDATA") def __init__(self, XMLStack=XMLObject.Stack()): self.Text = "" # ^^^ Generated code, do not modify ^^^ # vvv Generated code, do not modify vvv class BestFriend: ChildSpec = XMLObject.ChildClass({}, "") def __init__(self, ID, XMLStack=XMLObject.Stack()): self.ID = XMLStack.ReferenceID(ID, XMLStack) # ^^^ Generated code, do not modify ^^^ # vvv Generated code, do not modify vvv class User: ChildSpec = XMLObject.ChildClass({"Nickname": XMLObject.StdChild(Text, "Nickname", "Single", Reduce="Text"), "Email": XMLObject.StdChild( Text, "Email", "Single", Reduce="Text"), "Address": XMLObject.StdChild( Text, "Address", "List", Reduce="Text"), "City": XMLObject.StdChild( Text, "City", "Single", Reduce="Text"), "State": XMLObject.StdChild( Text, "State", "Single", Reduce="Text"), "Zip": XMLObject.StdChild( Text, "Zip", "Single", Reduce="Text"), "BestFriend": XMLObject.StdChild (BestFriend, "BestFriend", "Single", Reduce="ID")}, "(<Nickname>)?(<BestFriend>)?(<Email>)?(<Address>)*(<City>)?(<State>)?(<Zip>)?" ) def __init__(self, ID, XMLStack=XMLObject.Stack()): self.ID = XMLStack.UniqueID("User", ID, self, XMLStack) self.Nickname = "" self.Email = "" self.Address = [] self.City = "" self.State = "" self.Zip = "" self.BestFriend = "" # ^^^ Generated code, do not modify ^^^ def __repr__(self): RetVal = '<User ID="%s">' % self.ID if self.Nickname: RetVal += "<Nickname>%s</Nickname>" % self.Nickname if self.BestFriend: RetVal += '<BestFriend ID="%s" />' % self.Nickname if self.Email: RetVal += "<Email>%s</Email>" % self.Email for Address in self.Address: RetVal += "<Address>%s</Address>" % Address if self.City: RetVal += "<City>%s</City>" % self.City if self.State: RetVal += "<State>%s</State>" % self.State if self.Zip: RetVal += "<Zip>%s</Zip>" % self.Zip return RetVal + "</User>" # vvv Generated code, do not modify vvv class AddressBook: ChildSpec = XMLObject.ChildClass({"User": XMLObject.StdChild(User, "User", "Dict", Key="ID")}, "(<User>)*") def __init__(self, XMLStack=XMLObject.Stack()): self.User = {} # ^^^ Generated code, do not modify ^^^ def __repr__(self): RetVal = "<AddressBook>" for User in self.User.values(): RetVal += repr(User) return RetVal + "</AddressBook>" >>> import XMLObject, AddressBook2 >>> Book = XMLObject.Parse("AddressBook.xml", "AddressBook", ... AddressBook2.AddressBook) >>> repr(Book) '<AddressBook><User ID="1"><Nickname>Gre7g</Nickname><Email>gre7g@wolfhome.com< /Email><Address>2235 West Sunnyside Dr.</Address><City>Cedar City</City><State> MT</State><Zip>74720</Zip></User><User ID="2"><Nickname>Jimbo</Nickname><BestFr iend ID="Jimbo" /><Email>jimbo@hotmail.com</Email><Address>115 North Main</Addr ess><Address>Apartment #309</Address><City>Columbia</City><State>MO</State><Zip >65201</Zip></User></AddressBook>' |