"""xmlcreate.py: For creating XML files from scratch. For full documentation, see: http://www.nmt.edu/tcc/help/pubs/pyxml/ """ #================================================================ # Imports #---------------------------------------------------------------- import sys # For sysout stream import xml.dom.minidom as dom # Mini-Document Object Model import xml.dom.ext as domExt # For the PrettyPrint() function # - - - - - c l a s s D o c u m e n t - - - - - class Document: """Represents an XML document. State/invariants: .node: [ the DOM Document node ] """ # - - - D o c u m e n t . _ _ i n i t _ _ - - - def __init__ ( self ): """Constructor for Document. [ return a new, empty Document object ] """ #-- 1 -- # [ self.node := a new DOM Document node whose # .ownerDocument attribute points to itself ] self.node = dom.Document() self.node.ownerDocument = self.node # - - - D o c u m e n t . d o c t y p e - - - def doctype ( self, rootGI, systemId=None, publicId=None ): """Attach a document type to self. [ (self is a Document with no children) and (rootGI is the root element name) and (systemId is a system ID or None) and (publicId is a public ID or None) and (systemId and publicId are not both None) -> self := self with a document type attached whose root element name is rootGI, system ID systemId if given, and public ID publicId if given ] """ #-- 1 -- # [ dt := a new DOM DocumentType object with root=rootGI ] dt = dom.DocumentType ( rootGI ) #-- 2 -- # [ if systemId is None -> # I # else -> # dt := dt with system ID set to systemId ] if systemId is not None: dt.systemId = systemId #-- 3 -- # [ if publicId is None -> # I # else -> # dt := dt with public ID set to publicId ] if publicId is not None: dt.publicId = publicId #-- 4 -- # [ self := self with dt appended as a child ] self.node.appendChild ( dt ) # - - - D o c u m e n t . w r i t e - - - def write ( self, outFile=None ): """Prettyprint self in XML to outFile. [ outFile is a writeable file handle, defaulting to sys.stdout -> outFile +:= a prettyprinted XML representation of self ] """ #-- 1 -- if outFile is None: outFile = sys.stdout #-- 2 -- # [ outFile +:= an XML rendering of self.node ] domExt.PrettyPrint ( self.node, outFile ) # - - - - - c l a s s E l e m e n t - - - - - class Element: """Represents one XML element. State/Invariants: .node: [ a DOM Element node containing the actual element ] """ # - - - E l e m e n t . _ _ i n i t _ _ - - - def __init__ ( self, parent, gi, **attrs ): """Constructor for Element. [ (parent is an Element or Document object) -> parent := parent with a new XML element appended as its last or only child, having name=gi and attributes=attrs return that new element as Element object ] """ #-- 1 -- # [ parent is an Element -> # self.node := a new DOM Element with name=gi ] self.node = parent.node.ownerDocument.createElement ( gi ) #-- 2 -- # [ parent := parent with self.node appended as its next or # only child ] parent.node.appendChild ( self.node ) #-- 3 -- # [ self.node := self.node with attributes added from attrs ] for attrName in attrs: self.node.setAttribute ( attrName, attrs[attrName] ) # - - - E l e m e n t . _ _ s e t i t e m _ _ - - - def __setitem__ ( self, key, value ): """Add an attribute to self. [ key is an attribute name as a string -> self := self with its attribute (key) set to (value) ] """ self.node.setAttribute ( key, value ) # - - - - - c l a s s T e x t - - - - - class Text: """Represents a text node. State/Invariants: .node: [ a DOM Text node holding the text content ] """ # - - - T e x t . _ _ i n i t _ _ - - - def __init__ ( self, parent, content ): """Constructor for Text [ parent is an Element object -> parent := parent with a new text node added with text=content return a new Text object representing that text ] """ #-- 1 -- # [ parent is an Element -> # self.node := a new DOM Text node with content=content ] self.node = parent.node.ownerDocument.createTextNode ( content ) #-- 2 -- # [ parent := parent with self.node added as its next or # only child ] parent.node.appendChild ( self.node ) # - - - - - c l a s s C o m m e n t - - - - - class Comment: """Represents an XML comment.""" # - - - C o m m e n t . _ _ i n i t _ _ - - - def __init__ ( self, parent, content ): """Constructor for a Comment object. [ parent is an Element object -> parent := parent with a new comment node added with text=content return a new Comment object representing that node ] """ #-- 1 -- # [ parent is an Element -> # self.node := a new DOM Comment node with content=content ] self.node = parent.node.ownerDocument.createComment ( content ) #-- 2 -- # [ parent := parent with self.node added as its last or # only child ] parent.node.appendChild ( self.node ) # - - - - - c l a s s D o c u m e n t F r a g m e n t - - - - - class DocumentFragment: """Represents part of an XML document. State/Invariants: .node: [ a DOM DocumentFragment object whose .ownerDocument attribute contains a DOM Document instance ] """ # - - - D o c u m e n t F r a g m e n t . _ _ i n i t _ _ - - - def __init__ ( self ): """Constructor for DocumentFragment.""" #-- 1 -- # [ doc := a new, empty DOM Document object # self.node := a new, empty DOM DocumentFragment object ] doc = dom.Document() self.node = dom.DocumentFragment() #-- 2 -- self.node.ownerDocument = doc # - - - D o c u m e n t F r a g m e n t . w r i t e - - - def write ( self, outFile=None ): """Prettyprint self in XML to outFile.""" if outFile is None: outFile = sys.stdout domExt.PrettyPrint ( self.node, outFile )