1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
|
\section{\module{xml.dom.minidom} ---
The Document Object Model}
\declaremodule{standard}{xml.dom.minidom}
\modulesynopsis{Lightweight Document Object Model (DOM) implementation.}
\moduleauthor{Paul Prescod}{paul@prescod.net}
\sectionauthor{Paul Prescod}{paul@prescod.net}
\sectionauthor{Martin v. L\"owis}{loewis@informatik.hu-berlin.de}
\versionadded{2.0}
The \module{xml.dom.minidom} provides a light-weight implementation of
the W3C Document Object Model. The DOM is a cross-language API from
the Web Consortium (W3C) for accessing and modifying XML documents. A
DOM implementation allows to convert an XML document into a tree-like
structure, or to build such a structure from scratch. It then gives
access to the structure through a set of objects which provided
well-known interfaces. Minidom is intended to be simpler than the full
DOM and also significantly smaller.
The DOM is extremely useful for random-access applications. SAX only
allows you a view of one bit of the document at a time. If you are
looking at one SAX element, you have no access to another. If you are
looking at a text node, you have no access to a containing
element. When you write a SAX application, you need to keep track of
your program's position in the document somewhere in your own
code. Sax does not do it for you. Also, if you need to look ahead in
the XML document, you are just out of luck.
Some applications are simply impossible in an event driven model with
no access to a tree. Of course you could build some sort of tree
yourself in SAX events, but the DOM allows you to avoid writing that
code. The DOM is a standard tree representation for XML data.
%What if your needs are somewhere between SAX and the DOM? Perhaps you cannot
%afford to load the entire tree in memory but you find the SAX model
%somewhat cumbersome and low-level. There is also an experimental module
%called pulldom that allows you to build trees of only the parts of a
%document that you need structured access to. It also has features that allow
%you to find your way around the DOM.
% See http://www.prescod.net/python/pulldom
DOM applications typically start by parsing some XML into a DOM. This
is done through the parse functions:
\begin{verbatim}
from xml.dom.minidom import parse, parseString
dom1 = parse('c:\\temp\\mydata.xml') # parse an XML file by name
datasource = open('c:\\temp\\mydata.xml')
dom2 = parse(datasource) # parse an open file
dom3 = parseString('<myxml>Some data<empty/> some more data</myxml>')
\end{verbatim}
The parse function can take either a filename or an open file object.
\begin{funcdesc}{parse}{filename_or_file{, parser}}
Return a \class{Document} from the given input. \var{filename_or_file}
may be either a file name, or a file-like object. \var{parser}, if
given, must be a SAX2 parser object. This function will change the
document handler of the parser and activate namespace support; other
parser configuration (like setting an entity resolver) must have been
done in advance.
\end{funcdesc}
If you have XML in a string, you can use the parseString function
instead:
\begin{funcdesc}{parseString}{string\optional{, parser}}
Return a \class{Document} that represents the \var{string}. This
method creates a \class{StringIO} object for the string and passes
that on to \function{parse}.
\end{funcdesc}
Both functions return a document object representing the content of
the document.
You can also create a document node merely by instantiating a
document object. Then you could add child nodes to it to populate
the DOM.
\begin{verbatim}
from xml.dom.minidom import Document
newdoc = Document()
newel = newdoc.createElement("some_tag")
newdoc.appendChild(newel)
\end{verbatim}
Once you have a DOM document object, you can access the parts of your
XML document through its properties and methods. These properties are
defined in the DOM specification. The main property of the document
object is the documentElement property. It gives you the main element
in the XML document: the one that holds all others. Here is an
example program:
\begin{verbatim}
dom3 = parseString("<myxml>Some data</myxml>")
assert dom3.documentElement.tagName == "myxml"
\end{verbatim}
When you are finished with a DOM, you should clean it up. This is
necessary because some versions of Python do not support garbage
collection of objects that refer to each other in a cycle. Until this
restriction is removed from all versions of Python, it is safest to
write your code as if cycles would not be cleaned up.
The way to clean up a DOM is to call its \method{unlink()} method:
\begin{verbatim}
dom1.unlink()
dom2.unlink()
dom3.unlink()
\end{verbatim}
\method{unlink()} is a \module{minidom}-specific extension to the DOM
API. After calling \method{unlink()}, a DOM is basically useless.
\begin{seealso}
\seetitle[http://www.w3.org/TR/REC-DOM-Level-1/]{DOM Specification}
{This is the canonical specification for the level of the
DOM supported by \module{xml.dom.minidom}.}
\seetitle[http://pyxml.sourceforge.net]{PyXML}{Users that require a
full-featured implementation of DOM should use the PyXML
package.}
\end{seealso}
\subsection{DOM objects \label{dom-objects}}
The definitive documentation for the DOM is the DOM specification from
the W3C. This section lists the properties and methods supported by
\refmodule{xml.dom.minidom}.
\begin{classdesc}{Node}{}
All of the components of an XML document are subclasses of
\class{Node}.
\begin{memberdesc}{nodeType}
An integer representing the node type. Symbolic constants for the
types are on the \class{Node} object: \constant{DOCUMENT_NODE},
\constant{ELEMENT_NODE}, \constant{ATTRIBUTE_NODE},
\constant{TEXT_NODE}, \constant{CDATA_SECTION_NODE},
\constant{ENTITY_NODE}, \constant{PROCESSING_INSTRUCTION_NODE},
\constant{COMMENT_NODE}, \constant{DOCUMENT_NODE},
\constant{DOCUMENT_TYPE_NODE}, \constant{NOTATION_NODE}.
\end{memberdesc}
\begin{memberdesc}{parentNode}
The parent of the current node. \code{None} for the document node.
\end{memberdesc}
\begin{memberdesc}{attributes}
An \class{AttributeList} of attribute objects. Only
elements have this attribute. Others return \code{None}.
\end{memberdesc}
\begin{memberdesc}{previousSibling}
The node that immediately precedes this one with the same parent. For
instance the element with an end-tag that comes just before the
\var{self} element's start-tag. Of course, XML documents are made
up of more than just elements so the previous sibling could be text, a
comment, or something else.
\end{memberdesc}
\begin{memberdesc}{nextSibling}
The node that immediately follows this one with the same parent. See
also \member{previousSibling}.
\end{memberdesc}
\begin{memberdesc}{childNodes}
A list of nodes contained within this node.
\end{memberdesc}
\begin{memberdesc}{firstChild}
Equivalent to \code{childNodes[0]}.
\end{memberdesc}
\begin{memberdesc}{lastChild}
Equivalent to \code{childNodes[-1]}.
\end{memberdesc}
\begin{memberdesc}{nodeName}
Has a different meaning for each node type. See the DOM specification
for details. You can always get the information you would get here
from another property such as the \member{tagName} property for
elements or the \member{name} property for attributes.
\end{memberdesc}
\begin{memberdesc}{nodeValue}
Has a different meaning for each node type. See the DOM specification
for details. The situation is similar to that with \member{nodeName}.
\end{memberdesc}
\begin{methoddesc}{unlink}{}
Break internal references within the DOM so that it will be garbage
collected on versions of Python without cyclic GC.
\end{methoddesc}
\begin{methoddesc}{writexml}{writer}
Write XML to the writer object. The writer should have a
\method{write()} method which matches that of the file object
interface.
\end{methoddesc}
\begin{methoddesc}{toxml}{}
Return the XML string that the DOM represents.
\end{methoddesc}
\begin{methoddesc}{hasChildNodes}{}
Returns true the node has any child nodes.
\end{methoddesc}
\begin{methoddesc}{insertBefore}{newChild, refChild}
Insert a new child node before an existing child. It must be the case
that \var{refChild} is a child of this node; if not,
\exception{ValueError} is raised.
\end{methoddesc}
\begin{methoddesc}{replaceChild}{newChild, oldChild}
Replace an existing node with a new node. It must be the case that
\var{oldChild} is a child of this node; if not,
\exception{ValueError} is raised.
\end{methoddesc}
\begin{methoddesc}{removeChild}{oldChild}
Remove a child node. \var{oldChild} must be a child of this node; if
not, \exception{ValueError} is raised.
\end{methoddesc}
\begin{methoddesc}{appendChild}{newChild}
Add a new child node to this node list.
\end{methoddesc}
\begin{methoddesc}{cloneNode}{deep}
Clone this node. Deep means to clone all children also. Deep cloning
is not implemented in Python 2 so the deep parameter should always be
0 for now.
\end{methoddesc}
\end{classdesc}
\begin{classdesc}{Document}{}
Represents an entire XML document, including its constituent elements,
attributes, processing instructions, comments etc. Remeber that it
inherits properties from \class{Node}.
\begin{memberdesc}{documentElement}
The one and only root element of the document.
\end{memberdesc}
\begin{methoddesc}{createElement}{tagName}
Create a new element. The element is not inserted into the document
when it is created. You need to explicitly insert it with one of the
other methods such as \method{insertBefore()} or
\method{appendChild()}.
\end{methoddesc}
\begin{methoddesc}{createTextNode}{data}
Create a text node containing the data passed as a parameter. As with
the other creation methods, this one does not insert the node into the
tree.
\end{methoddesc}
\begin{methoddesc}{createComment}{data}
Create a comment node containing the data passed as a parameter. As
with the other creation methods, this one does not insert the node
into the tree.
\end{methoddesc}
\begin{methoddesc}{createProcessingInstruction}{target, data}
Create a processing instruction node containing the \var{target} and
\var{data} passed as parameters. As with the other creation methods,
this one does not insert the node into the tree.
\end{methoddesc}
\begin{methoddesc}{createAttribute}{name}
Create an attribute node. This method does not associate the
attribute node with any particular element. You must use
\method{setAttributeNode()} on the appropriate \class{Element} object
to use the newly created attribute instance.
\end{methoddesc}
\begin{methoddesc}{createElementNS}{namespaceURI, tagName}
Create a new element with a namespace. The \var{tagName} may have a
prefix. The element is not inserted into the document when it is
created. You need to explicitly insert it with one of the other
methods such as \method{insertBefore()} or \method{appendChild()}.
\end{methoddesc}
\begin{methoddesc}{createAttributeNS}{namespaceURI, qualifiedName}
Create an attribute node with a namespace. The \var{tagName} may have
a prefix. This method does not associate the attribute node with any
particular element. You must use \method{setAttributeNode()} on the
appropriate \class{Element} object to use the newly created attribute
instance.
\end{methoddesc}
\begin{methoddesc}{getElementsByTagName}{tagName}
Search for all descendants (direct children, children's children,
etc.) with a particular element type name.
\end{methoddesc}
\begin{methoddesc}{getElementsByTagNameNS}{namespaceURI, localName}
Search for all descendants (direct children, children's children,
etc.) with a particular namespace URI and localname. The localname is
the part of the namespace after the prefix.
\end{methoddesc}
\end{classdesc}
\begin{classdesc}{Element}{}
\begin{memberdesc}{tagName}
The element type name. In a namespace-using document it may have
colons in it.
\end{memberdesc}
\begin{memberdesc}{localName}
The part of the \member{tagName} following the colon if there is one,
else the entire \member{tagName}.
\end{memberdesc}
\begin{memberdesc}{prefix}
The part of the \member{tagName} preceding the colon if there is one,
else the empty string.
\end{memberdesc}
\begin{memberdesc}{namespaceURI}
The namespace associated with the tagName.
\end{memberdesc}
\begin{methoddesc}{getAttribute}{attname}
Return an attribute value as a string.
\end{methoddesc}
\begin{methoddesc}{setAttribute}{attname, value}
Set an attribute value from a string.
\end{methoddesc}
\begin{methoddesc}{removeAttribute}{attname}
Remove an attribute by name.
\end{methoddesc}
\begin{methoddesc}{getAttributeNS}{namespaceURI, localName}
Return an attribute value as a string, given a \var{namespaceURI} and
\var{localName}. Note that a localname is the part of a prefixed
attribute name after the colon (if there is one).
\end{methoddesc}
\begin{methoddesc}{setAttributeNS}{namespaceURI, qname, value}
Set an attribute value from a string, given a \var{namespaceURI} and a
\var{qname}. Note that a qname is the whole attribute name. This is
different than above.
\end{methoddesc}
\begin{methoddesc}{removeAttributeNS}{namespaceURI, localName}
Remove an attribute by name. Note that it uses a localName, not a
qname.
\end{methoddesc}
\begin{methoddesc}{getElementsByTagName}{tagName}
Same as equivalent method in the \class{Document} class.
\end{methoddesc}
\begin{methoddesc}{getElementsByTagNameNS}{tagName}
Same as equivalent method in the \class{Document} class.
\end{methoddesc}
\end{classdesc}
\begin{classdesc}{Attribute}{}
\begin{memberdesc}{name}
The attribute name. In a namespace-using document it may have colons
in it.
\end{memberdesc}
\begin{memberdesc}{localName}
The part of the name following the colon if there is one, else the
entire name.
\end{memberdesc}
\begin{memberdesc}{prefix}
The part of the name preceding the colon if there is one, else the
empty string.
\end{memberdesc}
\begin{memberdesc}{namespaceURI}
The namespace associated with the attribute name.
\end{memberdesc}
\end{classdesc}
\begin{classdesc}{AttributeList}{}
\begin{memberdesc}{length}
The length of the attribute list.
\end{memberdesc}
\begin{methoddesc}{item}{index}
Return an attribute with a particular index. The order you get the
attributes in is arbitrary but will be consistent for the life of a
DOM. Each item is an attribute node. Get its value with the
\member{value} attribbute.
\end{methoddesc}
There are also experimental methods that give this class more
dictionary-like behavior. You can use them or you can use the
standardized \method{getAttribute*()}-family methods.
\end{classdesc}
\begin{classdesc}{Comment}{}
Represents a comment in the XML document.
\begin{memberdesc}{data}
The content of the comment.
\end{memberdesc}
\end{classdesc}
\begin{classdesc}{Text}{}
Represents text in the XML document.
\begin{memberdesc}{data}
The content of the text node.
\end{memberdesc}
\end{classdesc}
\begin{classdesc}{ProcessingInstruction}{}
Represents a processing instruction in the XML document.
\begin{memberdesc}{target}
The content of the processing instruction up to the first whitespace
character.
\end{memberdesc}
\begin{memberdesc}{data}
The content of the processing instruction following the first
whitespace character.
\end{memberdesc}
\end{classdesc}
Note that DOM attributes may also be manipulated as nodes instead of as
simple strings. It is fairly rare that you must do this, however, so this
usage is not yet documented here.
\begin{seealso}
\seetitle[http://www.w3.org/TR/REC-DOM-Level-1/]{DOM Specification}
{This is the canonical specification for the level of the
DOM supported by \module{xml.dom.minidom}.}
\end{seealso}
\subsection{DOM Example \label{dom-example}}
This example program is a fairly realistic example of a simple
program. In this particular case, we do not take much advantage
of the flexibility of the DOM.
\begin{verbatim}
from xml.dom.minidom import parse, parseString
document="""
<slideshow>
<title>Demo slideshow</title>
<slide><title>Slide title</title>
<point>This is a demo</point>
<point>Of a program for processing slides</point>
</slide>
<slide><title>Another demo slide</title>
<point>It is important</point>
<point>To have more than</point>
<point>one slide</point>
</slide>
</slideshow>
"""
dom = parseString(document)
space=" "
def getText(nodelist):
rc=""
for node in nodelist:
if node.nodeType==node.TEXT_NODE:
rc=rc+node.data
return rc
def handleSlideshow(slideshow):
print "<html>"
handleSlideshowTitle(slideshow.getElementsByTagName("title")[0])
slides = slideshow.getElementsByTagName("slide")
handleToc(slides)
handleSlides(slides)
print "</html>"
def handleSlides(slides):
for slide in slides:
handleSlide(slide)
def handleSlide(slide):
handleSlideTitle(slide.getElementsByTagName("title")[0])
handlePoints(slide.getElementsByTagName("point"))
def handleSlideshowTitle(title):
print "<title>%s</title>"%getText(title.childNodes)
def handleSlideTitle(title):
print "<h2>%s</h2>"%getText(title.childNodes)
def handlePoints(points):
print "<ul>"
for point in points:
handlePoint(point)
print "</ul>"
def handlePoint(point):
print "<li>%s</li>"%getText(point.childNodes)
def handleToc(slides):
for slide in slides:
title = slide.getElementsByTagName("title")[0]
print "<p>%s</p>"%getText(title.childNodes)
handleSlideshow(dom)
\end{verbatim}
\subsection{minidom and the DOM standard \label{minidom-and-dom}}
Minidom is basically a DOM 1.0-compatible DOM with some DOM 2 features
(primarily namespace features).
Usage of the other DOM interfaces in Python is straight-forward. The
following mapping rules apply:
\begin{itemize}
\item Interfaces are accessed through instance objects. Applications
should
not instantiate the classes themselves; they should use the creator
functions. Derived interfaces support all operations (and attributes)
from the base interfaces, plus any new operations.
\item Operations are used as methods. Since the DOM uses only
\code{in}
parameters, the arguments are passed in normal order (from left to
right).
There are no optional arguments. \code{void} operations return
\code{None}.
\item IDL attributes map to instance attributes. For compatibility
with
the OMG IDL language mapping for Python, an attribute \code{foo} can
also be accessed through accessor functions \code{_get_foo} and
\code{_set_foo}. \code{readonly} attributes must not be changed.
\item The types \code{short int},\code{unsigned int},\code{unsigned
long long},
and \code{boolean} all map to Python integer objects.
\item The type \code{DOMString} maps to Python strings. \code{minidom}
supports either byte or Unicode strings, but will normally produce
Unicode
strings. Attributes of type \code{DOMString} may also be \code{None}.
\item \code{const} declarations map to variables in their respective
scope
(e.g. \code{xml.dom.minidom.Node.PROCESSING_INSTRUCTION_NODE}); they
must
not be changed.
\item \code{DOMException} is currently not supported in
\module{minidom}. Instead, minidom returns standard Python exceptions
such as TypeError and AttributeError.
\end{itemize}
The following interfaces have no equivalent in minidom:
\begin{itemize}
\item DOMTimeStamp
\item DocumentType
\item DOMImplementation
\item CharacterData
\item CDATASection
\item Notation
\item Entity
\item EntityReference
\item DocumentFragment
\end{itemize}
Most of these reflect information in the XML document that is not of
general utility to most DOM users.
|