Simple interface to minidom for creating XML files

Raphaël Plasson rplasson at gmail.com
Mon Sep 27 06:20:56 CEST 2010


Hello,

I want to create some XML files, following a simple template. For that
purpose, I created a simple interface to minidom. This is simple code,
but as I spend a little time for understanding how minidom was
working, I thought that this may be useful for someone (not that
minidom is complex, but even if simplified from the full XML
implementation, it still possesses too many functions for what I
simply wanted to do).

What you have to do is just to import the class doc, and then:

In [258]: xml=doc("toto")
In [259]: xml["part1"]=None
In [260]: xml["part1"]["1.1"]="coucou"
In [261]: xml["part1"]["1.2"]="toto"
In [262]: xml["part1"]["1.2"]["1.2.1"]="a"
In [263]: xml["part1"]["1.2"]["1.2.2"]="b"
In [264]: xml["part2"]="That's all folks!"
In [265]: xml["part1"]["1.2"]["1.2.2"]="really b"
In [266]: xml["part1"]["cdata"]="This is\nMore complex data\n:-p\n"
In [267]: xml.write("test.xml")

is sufficient to obtain the following file:

<?xml version="1.0" ?>
<toto>
    <part1>
        <1.1>
            coucou
        </1.1>
        <1.2>
            toto
            <1.2.1>
                a
            </1.2.1>
            <1.2.2>
                really b
            </1.2.2>
        </1.2>
<![CDATA[This is
More complex data
:-p
]]>
    </part1>
    <part2>
        That's all folks!
    </part2>
</toto>

This piece of code is way too small for being considered as a real
package, but it may help someone. Thus, I am just posting it here so
that it doesn't get lost. Please feel free to use it and extend it as
will (I put a GPL licence in that purpose).
If you have some comments/suggestion about this code, I would also be
happy to discuss about it :).

Raphaël


Here is the code:

8x-----------------------------------------------------------------------
x8

# Copyright 2010 Raphael Plasson, rplasson_at_gmail_dot_com
#
# This program is free software: you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/
>.

from xml.dom.minidom import Document

class node:
    def __init__(self,name,parent,doc):
        '''Add a node called <name> to the document <doc> inside the
node <parent>'''
        self.name=name
        self.parent=parent
        self.doc=doc
        self.element=self.doc.createElement(self.name)
        self.parent.element.appendChild(self.element)
        self.children={}
    def __getitem__(self,key):
        return self.children[key]
    def __setitem__(self,key,val):
        if key=="text":
            self.set_text(val)
        elif key=="cdata":
            self.set_cdata(val)
        else:
            tmp=self.set_node(key)
            if val != None:
                tmp.set_text(val)
    def __repr__(self):
        tmp=self.name+" : "
        for i in self.children:
            tmp += i+", "
        return tmp
    def __newchild(self,child,name):
        self.children[name] = child
    def set_node(self,name):
        '''Add a node <name>.
        If a node with the same name already exists,
        it is simply returned.'''
        if self.children.has_key(name):
            return self.children[name]
        else:
            tmp=node(name,self,self.doc)
            self.__newchild(tmp,name)
            return tmp
    def set_text(self,text):
        '''Add or update the node text <text>'''
        if self.children.has_key("text"):
            self.children["text"].data=text
        else:
            tmp=self.doc.createTextNode(text)
            self.__newchild(tmp,"text")
            self.element.appendChild(tmp)
    def set_cdata(self,cdata):
        '''Add or update the node cdata <cdata>'''
        if self.children.has_key("cdata"):
            self.children["cdata"].data=cdata
        else:
            tmp=self.doc.createCDATASection(cdata)
            self.__newchild(tmp,"cdata")
            self.element.appendChild(tmp)
            self.element.appendChild(self.doc.createTextNode(""))  #
dirty hack for adding newline after CDATA in file
    def set_attr(self,attr,val):
        '''Add or set the attribute <attr> to <val>'''
        self.element.setAttribute(attr,val)
    def comment(self,comm):
        '''Add the comment <comm>'''
        self.element.appendChild(self.doc.createComment(comm))

class doc(node):
    def __init__(self,name):
        ''' Create an xml document, with root node <name>'''
        self.name=name
        self.parent=None
        self.doc=Document()
        self.element=self.doc.createElement(self.name)
        self.doc.appendChild(self.element)
        self.children={}
        self.text=""
    def write(self,filename):
        ''' Write the xml document to <filename>'''
        out=file(filename,"w")
        self.doc.writexml(out, newl="\n", addindent="    ")
        out.close()

8x-----------------------------------------------------------------------
x8



More information about the Python-list mailing list