[XML-SIG] Simple DOM question (writing DOM)

Gerhard Häring haering_python@gmx.de
Wed, 12 Dec 2001 09:20:20 +0100


Le 12/12/01 ā 07:13, Martin v. Loewis écrivit:
> > I'm quite new to actually using XML and I'm confused. Parsing a XML
> > document and building a data structure went fine, but now I want to give
> > my data structure a toxml() method that creates an Element again.
> 
> Is that a custom data structure, or a DOM tree? By "create an
> Element", do you mean you want to create some data structure, or an
> XML file (i.e. a sequence of bytes in a stream, or on disk)?

I want my classes to be able to represent itself as a DOM element node
as well as reconstruct themselves from such an element node.

> > How would I create an element? With the createElement method of the
> > Document interface? Now, the problem is that I don't have a Document
> > yet. And if I want to create one, I wouldn't even know how to create an
> > empty one.
> 
> It sounds like you want to serialize your data structure into XML.

Yes!

> The best approach to do that is print/write:

If I had proposed that at my former job, I guess I would have been
killed. Seriously? Or is it just that I did my little XML work in Java
and the Java culture shows? This sounds a little bit too unstructured to
me. Btw. I've meanwhile got the transformation from/to XML working. I'm
quite happy with it and it's not too much work in comparison with
print/write. Any comments?

So, here is it:

# file: xmlconstants.py
AddressBook = "AddressBook"
Groups = "Groups"
Contacts = "Contacts"
Contact = "Contact"

contactAttributes = ["Uid", "Title" "FirstName", "MiddleName" "LastName",
 "Suffix" "FileAs", "Categories" "DefaultEmail", "Emails" "HomeStreet",
 "HomeCity" "HomeState", "HomeZip" "HomeCountry", "HomePhone" "HomeFax",
 "HomeMobile" "HomeWebPage", "Company" "BusinessStreet", "BusinessCity"
 "BusinessState", "BusinessZip" "BusinessCountry", "BusinessWebPage" "JobTitle",
 "Department" "Office", "BusinessPhone" "BusinessFax", "BusinessMobile"
 "BusinessPager", "Profession" "Assistant", "Manager" "Spouse", "Children"
 "Gender", "Birthday" "Anniversary", "Nickname" "Notes", "action" "actionrow"]
# end file xmlconstants.py

# file: addressbook.py
#!/usr/bin/env python
from xml.dom import Document
from xml.dom.ext.reader.Sax import FromXmlStream
from xml.dom.DOMImplementation import implementation
from xml.dom.ext import PrettyPrint

import sys
import xml.dom.minidom

import xmlconstants

class Contacts:
    """A container for contacts. Will get methods for managing/searching
    contacts."""
    def __init__(self):
        self.contacts = []

    def add(self, contact):
        self.contacts.append(contact)

    def fromxml(self, contactsNode):
        for contactNode in contactsNode.getElementsByTagName(xmlconstants.Contact):
            contact = Contact()
            contact.fromxml(contactNode)
            self.add(contact)

    def toxml(self, doc):
        """Returns: an Element Node."""
        contactsNode = doc.createElement(xmlconstants.Contacts)
        for contact in self.contacts:
            contactsNode.appendChild(contact.toxml(doc))
        return contactsNode

class Contact:
    """Pretty stupid structure that has attributes serialized from/to XML
    *attributes* in a Contact element."""
    def __init__(self):
        for attr in xmlconstants.contactAttributes:
            self.__dict__[attr] = None

    def fromxml(self, node):
        for k in node.attributes.keys():
            attr = node.attributes[k]
            val = attr.nodeValue.encode("utf-8")
            self.__dict__[attr.nodeName] = val

    def toxml(self, doc):
        contactNode = doc.createElement(xmlconstants.Contact)
        for key, value in self.__dict__.items():
            if value != None:
                contactNode.setAttribute(key, value)
        return contactNode

# Creating DOM and creating data structure from DOM

doc = FromXmlStream(sys.stdin)
docElement = doc.documentElement

contacts = Contacts()
contactElement = docElement.getElementsByTagName(xmlconstants.Contacts)[0]
contacts.fromxml(contactElement)

# Creating and writing DOM from data structure

doc = implementation.createDocument(None, None, None)
#dom = xml.dom.minidom
addressbook = doc.createElement(xmlconstants.AddressBook)
doc.appendChild(addressbook)

c = contacts.toxml(doc)
addressbook.appendChild(c)

PrettyPrint(doc)
# end file addressbook.py

Gerhard
-- 
mail:   gerhard <at> bigfoot <dot> de       registered Linux user #64239
web:    http://www.cs.fhm.edu/~ifw00065/    OpenPGP public key id 86AB43C0
public key fingerprint: DEC1 1D02 5743 1159 CD20  A4B6 7B22 6575 86AB 43C0
reduce(lambda x,y:x+y,map(lambda x:chr(ord(x)^42),tuple('zS^BED\nX_FOY\x0b')))