Package elementtree ::
Module ElementTree
|
|
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 from __future__ import generators
82
83 __all__ = [
84
85 "Comment",
86 "dump",
87 "Element", "ElementTree",
88 "fromstring", "fromstringlist",
89 "iselement", "iterparse",
90 "parse", "ParseError",
91 "PI", "ProcessingInstruction",
92 "QName",
93 "SubElement",
94 "tostring", "tostringlist",
95 "TreeBuilder",
96 "VERSION",
97 "XML",
98 "XMLParser", "XMLTreeBuilder",
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 import sys, re
124
126
127 - def find(self, element, tag):
128 for elem in element:
129 if elem.tag == tag:
130 return elem
131 return None
132 - def findtext(self, element, tag, default=None):
133 for elem in element:
134 if elem.tag == tag:
135 return elem.text or ""
136 return default
138 if tag[:3] == ".//":
139 return element.getiterator(tag[3:])
140 result = []
141 for elem in element:
142 if elem.tag == tag:
143 result.append(elem)
144 return result
145
146 try:
147 import ElementPath
148 except ImportError:
149
150 ElementPath = _SimpleElementPath()
151
152 VERSION = "1.3a2"
153
156
157
158
159
160
161
162
163
164
165
167
168
169 return isinstance(element, Element) or hasattr(element, "tag")
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
187
188
189
190
191
192 tag = None
193
194
195
196
197
198
199
200
201
202 attrib = None
203
204
205
206
207
208 text = None
209
210
211
212
213
214
215 tail = None
216
217 - def __init__(self, tag, attrib={}, **extra):
223
225 return "<Element %s at %x>" % (repr(self.tag), id(self))
226
227
228
229
230
231
232
233
236
237
238
239
240
241
243 return len(self._children)
244
246 import warnings
247 warnings.warn(
248 "The behavior of this method will change in future versions. "
249 "Use specific 'len(elem)' or 'elem is not None' test instead.",
250 FutureWarning
251 )
252 return len(self._children) != 0
253
254
255
256
257
258
259
260
262 return self._children[index]
263
264
265
266
267
268
269
270
271
273 assert iselement(element)
274 self._children[index] = element
275
276
277
278
279
280
281
283 del self._children[index]
284
285
286
287
288
289
290
291
293 return self._children[start:stop]
294
295
296
297
298
299
300
301
302
304 for element in elements:
305 assert iselement(element)
306 self._children[start:stop] = list(elements)
307
308
309
310
311
312
313
315 del self._children[start:stop]
316
317
318
319
320
321
322
324 assert iselement(element)
325 self._children.append(element)
326
327
328
329
330
331
332
333
335 for element in elements:
336 assert iselement(element)
337 self._children.extend(elements)
338
339
340
341
342
343
344
345 - def insert(self, index, element):
346 assert iselement(element)
347 self._children.insert(index, element)
348
349
350
351
352
353
354
355
356
357
359 assert iselement(element)
360 self._children.remove(element)
361
362
363
364
365
366
367
368
370 import warnings
371 warnings.warn(
372 "This method will be removed in future versions. "
373 "Use 'list(elem)' or iteration over elem instead.",
374 DeprecationWarning
375 )
376 return self._children
377
378
379
380
381
382
383
384
385 - def find(self, path):
387
388
389
390
391
392
393
394
395
396
397
398
399 - def findtext(self, path, default=None):
400 return ElementPath.findtext(self, path, default)
401
402
403
404
405
406
407
408
409
412
413
414
415
416
418 self.attrib.clear()
419 self._children = []
420 self.text = self.tail = None
421
422
423
424
425
426
427
428
429
430
431 - def get(self, key, default=None):
432 return self.attrib.get(key, default)
433
434
435
436
437
438
439
440 - def set(self, key, value):
442
443
444
445
446
447
448
449
452
453
454
455
456
457
458
459
461 return self.attrib.items()
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476 - def iter(self, tag=None):
477 if tag == "*":
478 tag = None
479 if tag is None or self.tag == tag:
480 yield self
481 for e in self._children:
482 for e in e.iter(tag):
483 yield e
484
485
486 getiterator = iter
487
488
489
490
491
492
493
494
495
496
497
498
499 - def itertext(self):
500 if self.text:
501 yield self.text
502 for e in self:
503 for s in e.itertext():
504 yield s
505 if e.tail:
506 yield e.tail
507
508
509 _Element = _ElementInterface = Element
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
531
532
533
534
535
536
537
538
539
540
541
542
543
548
549
550
551
552
553
554
555
556
557
558
560 element = Element(ProcessingInstruction)
561 element.text = target
562 if text:
563 element.text = element.text + " " + text
564 return element
565
566 PI = ProcessingInstruction
567
568
569
570
571
572
573
574
575
576
577
579 - def __init__(self, text_or_uri, tag=None):
580 if tag:
581 text_or_uri = "{%s}%s" % (text_or_uri, tag)
582 self.text = text_or_uri
586 return hash(self.text)
588 if isinstance(other, QName):
589 return cmp(self.text, other.text)
590 return cmp(self.text, other)
591
592
593
594
595
596
597
598
599
600
601
602
604
605 - def __init__(self, element=None, file=None):
606 assert element is None or iselement(element)
607 self._root = element
608 if file:
609 self.parse(file)
610
611
612
613
614
615
616
619
620
621
622
623
624
625
626
628 assert iselement(element)
629 self._root = element
630
631
632
633
634
635
636
637
638
639
640 - def parse(self, source, parser=None):
652
653
654
655
656
657
658
659
660
661 - def iter(self, tag=None):
662 assert self._root is not None
663 return self._root.iter(tag)
664
665 getiterator = iter
666
667
668
669
670
671
672
673
674
675 - def find(self, path):
676 assert self._root is not None
677 if path[:1] == "/":
678 path = "." + path
679 import warnings
680 warnings.warn(
681 "This search is broken in 1.3 and earlier; if you rely "
682 "on the current behaviour, change it to %r" % path,
683 FutureWarning
684 )
685 return self._root.find(path)
686
687
688
689
690
691
692
693
694
695
696
697
698
699 - def findtext(self, path, default=None):
700 assert self._root is not None
701 if path[:1] == "/":
702 path = "." + path
703 import warnings
704 warnings.warn(
705 "This search is broken in 1.3 and earlier; if you rely "
706 "on the current behaviour, change it to %r" % path,
707 FutureWarning
708 )
709 return self._root.findtext(path, default)
710
711
712
713
714
715
716
717
718
719
721 assert self._root is not None
722 if path[:1] == "/":
723 path = "." + path
724 import warnings
725 warnings.warn(
726 "This search is broken in 1.3 and earlier; if you rely "
727 "on the current behaviour, change it to %r" % path,
728 FutureWarning
729 )
730 return self._root.findall(path)
731
732
733
734
735
736
737
738
739
740
741
742
743 - def write(self, file,
744
745 encoding="us-ascii",
746 xml_declaration=None,
747 default_namespace=None,
748 method=None):
749 assert self._root is not None
750 if not hasattr(file, "write"):
751 file = open(file, "wb")
752 write = file.write
753 if not method:
754 method = "xml"
755 if not encoding:
756 encoding = "us-ascii"
757 elif xml_declaration or (xml_declaration is None and
758 encoding not in ("utf-8", "us-ascii")):
759 write("<?xml version='1.0' encoding='%s'?>\n" % encoding)
760 if method == "text":
761 _serialize_text(write, self._root, encoding)
762 else:
763 qnames, namespaces = _namespaces(
764 self._root, encoding, default_namespace
765 )
766 if method == "xml":
767 _serialize_xml(
768 write, self._root, encoding, qnames, namespaces
769 )
770 elif method == "html":
771 _serialize_html(
772 write, self._root, encoding, qnames, namespaces
773 )
774 else:
775 raise ValueError("unknown method %r" % method)
776
777
778
779
780 -def _namespaces(elem, encoding, default_namespace=None):
781
782
783
784 qnames = {None: None}
785
786
787 namespaces = {}
788 if default_namespace:
789 namespaces[default_namespace] = ""
790
791 def encode(text):
792 return text.encode(encoding)
793
794 def add_qname(qname):
795
796 try:
797 if qname[:1] == "{":
798 uri, tag = qname[1:].split("}", 1)
799 prefix = namespaces.get(uri)
800 if prefix is None:
801 prefix = _namespace_map.get(uri)
802 if prefix is None:
803 prefix = "ns%d" % len(namespaces)
804 if prefix != "xml":
805 namespaces[uri] = prefix
806 if prefix:
807 qnames[qname] = encode("%s:%s" % (prefix, tag))
808 else:
809 qnames[qname] = encode(tag)
810 else:
811 if default_namespace:
812
813 raise ValueError(
814 "cannot use non-qualified names with "
815 "default_namespace option"
816 )
817 qnames[qname] = encode(qname)
818 except TypeError:
819 _raise_serialization_error(qname)
820
821
822 try:
823 iterate = elem.iter
824 except AttributeError:
825 iterate = elem.getiterator
826 for elem in iterate():
827 tag = elem.tag
828 if isinstance(tag, QName) and tag.text not in qnames:
829 add_qname(tag.text)
830 elif isinstance(tag, basestring):
831 if tag not in qnames:
832 add_qname(tag)
833 elif tag is not None and tag is not Comment and tag is not PI:
834 _raise_serialization_error(tag)
835 for key, value in elem.items():
836 if isinstance(key, QName):
837 key = key.text
838 if key not in qnames:
839 add_qname(key)
840 if isinstance(value, QName) and value.text not in qnames:
841 add_qname(value.text)
842 text = elem.text
843 if isinstance(text, QName) and text.text not in qnames:
844 add_qname(text.text)
845 return qnames, namespaces
846
848 tag = elem.tag
849 text = elem.text
850 if tag is Comment:
851 write("<!--%s-->" % _escape_cdata(text, encoding))
852 elif tag is ProcessingInstruction:
853 write("<?%s?>" % _escape_cdata(text, encoding))
854 else:
855 tag = qnames[tag]
856 if tag is None:
857 if text:
858 write(_escape_cdata(text, encoding))
859 for e in elem:
860 _serialize_xml(write, e, encoding, qnames, None)
861 else:
862 write("<" + tag)
863 items = elem.items()
864 if items or namespaces:
865 items.sort()
866 for k, v in items:
867 if isinstance(k, QName):
868 k = k.text
869 if isinstance(v, QName):
870 v = qnames[v.text]
871 else:
872 v = _escape_attrib(v, encoding)
873 write(" %s=\"%s\"" % (qnames[k], v))
874 if namespaces:
875 items = namespaces.items()
876 items.sort(key=lambda x: x[1])
877 for v, k in items:
878 if k:
879 k = ":" + k
880 write(" xmlns%s=\"%s\"" % (
881 k.encode(encoding),
882 _escape_attrib(v, encoding)
883 ))
884 if text or len(elem):
885 write(">")
886 if text:
887 write(_escape_cdata(text, encoding))
888 for e in elem:
889 _serialize_xml(write, e, encoding, qnames, None)
890 write("</" + tag + ">")
891 else:
892 write(" />")
893 if elem.tail:
894 write(_escape_cdata(elem.tail, encoding))
895
896 HTML_EMPTY = ("area", "base", "basefont", "br", "col", "frame", "hr",
897 "img", "input", "isindex", "link", "meta" "param")
898
899 try:
900 HTML_EMPTY = set(HTML_EMPTY)
901 except NameError:
902 pass
903
905 tag = elem.tag
906 text = elem.text
907 if tag is Comment:
908 write("<!--%s-->" % _escape_cdata(text, encoding))
909 elif tag is ProcessingInstruction:
910 write("<?%s?>" % _escape_cdata(text, encoding))
911 else:
912 tag = qnames[tag]
913 if tag is None:
914 if text:
915 write(_escape_cdata(text, encoding))
916 for e in elem:
917 _serialize_html(write, e, encoding, qnames, None)
918 else:
919 write("<" + tag)
920 items = elem.items()
921 if items or namespaces:
922 items.sort()
923 for k, v in items:
924 if isinstance(k, QName):
925 k = k.text
926 if isinstance(v, QName):
927 v = qnames[v.text]
928 else:
929 v = _escape_attrib_html(v, encoding)
930
931 write(" %s=\"%s\"" % (qnames[k], v))
932 if namespaces:
933 items = namespaces.items()
934 items.sort(key=lambda x: x[1])
935 for v, k in items:
936 if k:
937 k = ":" + k
938 write(" xmlns%s=\"%s\"" % (
939 k.encode(encoding),
940 _escape_attrib(v, encoding)
941 ))
942 write(">")
943 tag = tag.lower()
944 if text:
945 if tag == "script" or tag == "style":
946 write(_encode(text, encoding))
947 else:
948 write(_escape_cdata(text, encoding))
949 for e in elem:
950 _serialize_html(write, e, encoding, qnames, None)
951 if tag not in HTML_EMPTY:
952 write("</" + tag + ">")
953 if elem.tail:
954 write(_escape_cdata(elem.tail, encoding))
955
956 -def _serialize_text(write, elem, encoding):
957 for part in elem.itertext():
958 write(part.encode(encoding))
959 if elem.tail:
960 write(elem.tail.encode(encoding))
961
962
963
964
965
966
967
968
969
970
971
972
980
981 _namespace_map = {
982
983 "http://www.w3.org/XML/1998/namespace": "xml",
984 "http://www.w3.org/1999/xhtml": "html",
985 "http://www.w3.org/1999/02/22-rdf-syntax-ns#": "rdf",
986 "http://schemas.xmlsoap.org/wsdl/": "wsdl",
987
988 "http://www.w3.org/2001/XMLSchema": "xs",
989 "http://www.w3.org/2001/XMLSchema-instance": "xsi",
990
991 "http://purl.org/dc/elements/1.1/": "dc",
992 }
993
995 raise TypeError(
996 "cannot serialize %r (type %s)" % (text, type(text).__name__)
997 )
998
1000 try:
1001 return text.encode(encoding, "xmlcharrefreplace")
1002 except (TypeError, AttributeError):
1003 _raise_serialization_error(text)
1004
1006
1007 try:
1008
1009
1010
1011 if "&" in text:
1012 text = text.replace("&", "&")
1013 if "<" in text:
1014 text = text.replace("<", "<")
1015 if ">" in text:
1016 text = text.replace(">", ">")
1017 return text.encode(encoding, "xmlcharrefreplace")
1018 except (TypeError, AttributeError):
1019 _raise_serialization_error(text)
1020
1022
1023 try:
1024 if "&" in text:
1025 text = text.replace("&", "&")
1026 if "<" in text:
1027 text = text.replace("<", "<")
1028 if ">" in text:
1029 text = text.replace(">", ">")
1030 if "\"" in text:
1031 text = text.replace("\"", """)
1032 if "\n" in text:
1033 text = text.replace("\n", " ")
1034 return text.encode(encoding, "xmlcharrefreplace")
1035 except (TypeError, AttributeError):
1036 _raise_serialization_error(text)
1037
1039
1040 try:
1041 if "&" in text:
1042 text = text.replace("&", "&")
1043 if ">" in text:
1044 text = text.replace(">", ">")
1045 if "\"" in text:
1046 text = text.replace("\"", """)
1047 return text.encode(encoding, "xmlcharrefreplace")
1048 except (TypeError, AttributeError):
1049 _raise_serialization_error(text)
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061 -def tostring(element, encoding=None, method=None):
1062 class dummy:
1063 pass
1064 data = []
1065 file = dummy()
1066 file.write = data.append
1067 ElementTree(element).write(file, encoding, method=method)
1068 return "".join(data)
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1080 class dummy:
1081 pass
1082 data = []
1083 file = dummy()
1084 file.write = data.append
1085 ElementTree(element).write(file, encoding)
1086
1087 return data
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1099
1100 if not isinstance(elem, ElementTree):
1101 elem = ElementTree(elem)
1102 elem.write(sys.stdout)
1103 tail = elem.getroot().tail
1104 if not tail or tail[-1] != "\n":
1105 sys.stdout.write("\n")
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118 -def parse(source, parser=None):
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134 -def iterparse(source, events=None, parser=None):
1140
1142
1143 - def __init__(self, source, events, parser):
1144 self._file = source
1145 self._events = []
1146 self._index = 0
1147 self.root = self._root = None
1148 self._parser = parser
1149
1150 parser = self._parser._parser
1151 append = self._events.append
1152 if events is None:
1153 events = ["end"]
1154 for event in events:
1155 if event == "start":
1156 try:
1157 parser.ordered_attributes = 1
1158 parser.specified_attributes = 1
1159 def handler(tag, attrib_in, event=event, append=append,
1160 start=self._parser._start_list):
1161 append((event, start(tag, attrib_in)))
1162 parser.StartElementHandler = handler
1163 except AttributeError:
1164 def handler(tag, attrib_in, event=event, append=append,
1165 start=self._parser._start):
1166 append((event, start(tag, attrib_in)))
1167 parser.StartElementHandler = handler
1168 elif event == "end":
1169 def handler(tag, event=event, append=append,
1170 end=self._parser._end):
1171 append((event, end(tag)))
1172 parser.EndElementHandler = handler
1173 elif event == "start-ns":
1174 def handler(prefix, uri, event=event, append=append):
1175 try:
1176 uri = uri.encode("ascii")
1177 except UnicodeError:
1178 pass
1179 append((event, (prefix or "", uri)))
1180 parser.StartNamespaceDeclHandler = handler
1181 elif event == "end-ns":
1182 def handler(prefix, event=event, append=append):
1183 append((event, None))
1184 parser.EndNamespaceDeclHandler = handler
1185
1187 while 1:
1188 try:
1189 item = self._events[self._index]
1190 except IndexError:
1191 if self._parser is None:
1192 self.root = self._root
1193 raise StopIteration
1194
1195 del self._events[:]
1196 self._index = 0
1197 data = self._file.read(16384)
1198 if data:
1199 self._parser.feed(data)
1200 else:
1201 self._root = self._parser.close()
1202 self._parser = None
1203 else:
1204 self._index = self._index + 1
1205 return item
1206
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220 -def XML(text, parser=None):
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236 -def XMLID(text, parser=None):
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256 fromstring = XML
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1289
1290 - def __init__(self, element_factory=None):
1291 self._data = []
1292 self._elem = []
1293 self._last = None
1294 self._tail = None
1295 if element_factory is None:
1296 element_factory = Element
1297 self._factory = element_factory
1298
1299
1300
1301
1302
1303
1304
1305
1307 assert len(self._elem) == 0, "missing end tags"
1308 assert self._last != None, "missing toplevel element"
1309 return self._last
1310
1312 if self._data:
1313 if self._last is not None:
1314 text = "".join(self._data)
1315 if self._tail:
1316 assert self._last.tail is None, "internal error (tail)"
1317 self._last.tail = text
1318 else:
1319 assert self._last.text is None, "internal error (text)"
1320 self._last.text = text
1321 self._data = []
1322
1323
1324
1325
1326
1327
1328
1329 - def data(self, data):
1330 self._data.append(data)
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340 - def start(self, tag, attrs):
1341 self._flush()
1342 self._last = elem = self._factory(tag, attrs)
1343 if self._elem:
1344 self._elem[-1].append(elem)
1345 self._elem.append(elem)
1346 self._tail = 0
1347 return elem
1348
1349
1350
1351
1352
1353
1354
1355
1356 - def end(self, tag):
1357 self._flush()
1358 self._last = self._elem.pop()
1359 assert self._last.tag == tag,\
1360 "end tag mismatch (expected %s, got %s)" % (
1361 self._last.tag, tag)
1362 self._tail = 1
1363 return self._last
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1379
1380 - def __init__(self, html=0, target=None, encoding=None):
1381 try:
1382 from xml.parsers import expat
1383 except ImportError:
1384 try:
1385 import pyexpat; expat = pyexpat
1386 except ImportError:
1387 raise ImportError(
1388 "No module named expat; use SimpleXMLTreeBuilder instead"
1389 )
1390 parser = expat.ParserCreate(encoding, "}")
1391 if target is None:
1392 target = TreeBuilder()
1393
1394 self.parser = self._parser = parser
1395 self.target = self._target = target
1396 self._error = expat.error
1397 self._names = {}
1398
1399 parser.DefaultHandlerExpand = self._default
1400 parser.StartElementHandler = self._start
1401 parser.EndElementHandler = self._end
1402 parser.CharacterDataHandler = self._data
1403
1404 try:
1405 self._parser.buffer_text = 1
1406 except AttributeError:
1407 pass
1408
1409 try:
1410 self._parser.ordered_attributes = 1
1411 self._parser.specified_attributes = 1
1412 parser.StartElementHandler = self._start_list
1413 except AttributeError:
1414 pass
1415 self._doctype = None
1416 self.entity = {}
1417 try:
1418 self.version = "Expat %d.%d.%d" % expat.version_info
1419 except AttributeError:
1420 pass
1421
1423 err = ParseError(value)
1424 err.code = value.code
1425 err.position = value.lineno, value.offset
1426 raise err
1427
1428 - def _fixtext(self, text):
1429
1430 try:
1431 return text.encode("ascii")
1432 except UnicodeError:
1433 return text
1434
1445
1446 - def _start(self, tag, attrib_in):
1447 fixname = self._fixname
1448 fixtext = self._fixtext
1449 tag = fixname(tag)
1450 attrib = {}
1451 for key, value in attrib_in.items():
1452 attrib[fixname(key)] = fixtext(value)
1453 return self.target.start(tag, attrib)
1454
1456 fixname = self._fixname
1457 fixtext = self._fixtext
1458 tag = fixname(tag)
1459 attrib = {}
1460 if attrib_in:
1461 for i in range(0, len(attrib_in), 2):
1462 attrib[fixname(attrib_in[i])] = fixtext(attrib_in[i+1])
1463 return self.target.start(tag, attrib)
1464
1466 return self.target.data(self._fixtext(text))
1467
1468 - def _end(self, tag):
1469 return self.target.end(self._fixname(tag))
1470
1472 prefix = text[:1]
1473 if prefix == "&":
1474
1475 try:
1476 self.target.data(self.entity[text[1:-1]])
1477 except KeyError:
1478 from xml.parsers import expat
1479 err = expat.error(
1480 "undefined entity %s: line %d, column %d" %
1481 (text, self._parser.ErrorLineNumber,
1482 self._parser.ErrorColumnNumber)
1483 )
1484 err.code = 11
1485 err.lineno = self._parser.ErrorLineNumber
1486 err.offset = self._parser.ErrorColumnNumber
1487 raise err
1488 elif prefix == "<" and text[:9] == "<!DOCTYPE":
1489 self._doctype = []
1490 elif self._doctype is not None:
1491
1492 if prefix == ">":
1493 self._doctype = None
1494 return
1495 text = text.strip()
1496 if not text:
1497 return
1498 self._doctype.append(text)
1499 n = len(self._doctype)
1500 if n > 2:
1501 type = self._doctype[1]
1502 if type == "PUBLIC" and n == 4:
1503 name, type, pubid, system = self._doctype
1504 elif type == "SYSTEM" and n == 3:
1505 name, type, system = self._doctype
1506 pubid = None
1507 else:
1508 return
1509 if pubid:
1510 pubid = pubid[1:-1]
1511 if hasattr(self.target, "doctype"):
1512 self.target.doctype(name, pubid, system[1:-1])
1513 self._doctype = None
1514
1515
1516
1517
1518
1519
1520 - def feed(self, data):
1521 try:
1522 self._parser.Parse(data, 0)
1523 except self._error, v:
1524 self._raiseerror(v)
1525
1526
1527
1528
1529
1530
1531
1533 try:
1534 self._parser.Parse("", 1)
1535 except self._error, v:
1536 self._raiseerror(v)
1537 tree = self.target.close()
1538 del self.target, self._parser
1539 return tree
1540
1541
1542 XMLTreeBuilder = XMLParser
1543