summaryrefslogtreecommitdiffstats
path: root/Lib/xml/etree/cElementTree.py
blob: aaef59e519fdee56d9187b4ba02b242c384655f1 (plain)
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
# Wrapper module for _elementtree

from xml.etree.ElementTree import (ElementTree, dump, iselement, QName,
                                   fromstringlist,
                                   tostring, tostringlist, VERSION)
# These ones are not in ElementTree.__all__
from xml.etree.ElementTree import ElementPath, register_namespace

# Import the C accelerators:
#   Element, SubElement, TreeBuilder, XMLParser, ParseError
from _elementtree import *


class ElementTree(ElementTree):

    def parse(self, source, parser=None):
        close_source = False
        if not hasattr(source, 'read'):
            source = open(source, 'rb')
            close_source = True
        try:
            if parser is not None:
                while True:
                    data = source.read(65536)
                    if not data:
                        break
                    parser.feed(data)
                self._root = parser.close()
            else:
                parser = XMLParser()
                self._root = parser._parse(source)
            return self._root
        finally:
            if close_source:
                source.close()


class iterparse:
    root = None

    def __init__(self, file, events=None):
        self._close_file = False
        if not hasattr(file, 'read'):
            file = open(file, 'rb')
            self._close_file = True
        self._file = file
        self._events = []
        self._index = 0
        self._error = None
        self.root = self._root = None
        b = TreeBuilder()
        self._parser = XMLParser(b)
        self._parser._setevents(self._events, events)

    def __next__(self):
        while True:
            try:
                item = self._events[self._index]
                self._index += 1
                return item
            except IndexError:
                pass
            if self._error:
                e = self._error
                self._error = None
                raise e
            if self._parser is None:
                self.root = self._root
                if self._close_file:
                    self._file.close()
                raise StopIteration
            # load event buffer
            del self._events[:]
            self._index = 0
            data = self._file.read(16384)
            if data:
                try:
                    self._parser.feed(data)
                except SyntaxError as exc:
                    self._error = exc
            else:
                self._root = self._parser.close()
                self._parser = None

    def __iter__(self):
        return self


# =============================================================================
#
#   Everything below this line can be removed
#   after cElementTree is folded behind ElementTree.
#
# =============================================================================

from xml.etree.ElementTree import Comment as _Comment, PI as _PI


def parse(source, parser=None):
    tree = ElementTree()
    tree.parse(source, parser)
    return tree


def XML(text, parser=None):
    if not parser:
        parser = XMLParser()
    parser = XMLParser()
    parser.feed(text)
    return parser.close()


def XMLID(text, parser=None):
    tree = XML(text, parser=parser)
    ids = {}
    for elem in tree.iter():
        id = elem.get('id')
        if id:
            ids[id] = elem
    return tree, ids


class CommentProxy:

    def __call__(self, text=None):
        element = Element(_Comment)
        element.text = text
        return element

    def __eq__(self, other):
        return _Comment == other


class PIProxy:

    def __call__(self, target, text=None):
        element = Element(_PI)
        element.text = target
        if text:
            element.text = element.text + ' ' + text
        return element

    def __eq__(self, other):
        return _PI == other


Comment = CommentProxy()
PI = ProcessingInstruction = PIProxy()
del CommentProxy, PIProxy

# Aliases
fromstring = XML
XMLTreeBuilder = XMLParser