587
|
1 |
#============================================================================
|
|
2 |
#Name : amara.py
|
|
3 |
#Part of : Helium
|
|
4 |
|
|
5 |
#Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
|
6 |
#All rights reserved.
|
|
7 |
#This component and the accompanying materials are made available
|
|
8 |
#under the terms of the License "Eclipse Public License v1.0"
|
|
9 |
#which accompanies this distribution, and is available
|
|
10 |
#at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
|
11 |
#
|
|
12 |
#Initial Contributors:
|
|
13 |
#Nokia Corporation - initial contribution.
|
|
14 |
#
|
|
15 |
#Contributors:
|
|
16 |
#
|
|
17 |
#Description:
|
|
18 |
#===============================================================================
|
|
19 |
"""amara"""
|
|
20 |
|
628
|
21 |
# pylint: disable=E1103
|
|
22 |
#import sys
|
|
23 |
#if 'java' in sys.platform:
|
|
24 |
# pass
|
|
25 |
if True:
|
|
26 |
import os
|
587
|
27 |
import xml.dom.minidom
|
|
28 |
import urllib
|
628
|
29 |
import xpath
|
|
30 |
import xml.etree.ElementTree
|
|
31 |
import xml.etree.ElementInclude
|
|
32 |
|
|
33 |
# pylint: disable=W0212
|
|
34 |
def fixed_writexml(self, writer, indent="", addindent="", newl=""):
|
|
35 |
# indent = current indentation
|
|
36 |
# addindent = indentation to add to higher levels
|
|
37 |
# newl = newline string
|
|
38 |
writer.write(indent + "<" + self.tagName)
|
|
39 |
|
|
40 |
attrs = self._get_attributes()
|
|
41 |
a_names = attrs.keys()
|
|
42 |
a_names.sort()
|
|
43 |
|
|
44 |
for a_name in a_names:
|
|
45 |
writer.write(" %s=\"" % a_name)
|
|
46 |
xml.dom.minidom._write_data(writer, attrs[a_name].value)
|
|
47 |
writer.write("\"")
|
|
48 |
if self.childNodes:
|
|
49 |
if len(self.childNodes) == 1 \
|
|
50 |
and self.childNodes[0].nodeType == xml.dom.minidom.Node.TEXT_NODE:
|
|
51 |
writer.write(">")
|
|
52 |
self.childNodes[0].writexml(writer, "", "", "")
|
|
53 |
writer.write("</%s>%s" % (self.tagName, newl))
|
|
54 |
return
|
|
55 |
writer.write(">%s" % (newl))
|
|
56 |
for node in self.childNodes:
|
|
57 |
if node.__class__ == xml.dom.minidom.Text and node.data.strip() == '':
|
|
58 |
continue
|
|
59 |
node.writexml(writer, indent + addindent, addindent, newl)
|
|
60 |
writer.write("%s</%s>%s" % (indent, self.tagName, newl))
|
|
61 |
else:
|
|
62 |
writer.write("/>%s" % (newl))
|
|
63 |
# replace minidom's function with ours
|
|
64 |
xml.dom.minidom.Element.writexml = fixed_writexml
|
587
|
65 |
|
|
66 |
def parse(param):
|
|
67 |
"""parse"""
|
|
68 |
return MinidomAmara(param)
|
|
69 |
|
|
70 |
def create_document(name=None):
|
|
71 |
"""create document"""
|
|
72 |
impl = xml.dom.minidom.getDOMImplementation()
|
|
73 |
newdoc = impl.createDocument(None, name, None)
|
|
74 |
return MinidomAmara(newdoc)
|
|
75 |
|
|
76 |
class MinidomAmara(object):
|
|
77 |
""" amara api using minidom """
|
|
78 |
|
|
79 |
def __init__(self, dom, parent=None):
|
|
80 |
self.parent = parent
|
|
81 |
if isinstance(dom, file):
|
|
82 |
self.dom = xml.dom.minidom.parse(dom)
|
|
83 |
elif isinstance(dom, basestring):
|
628
|
84 |
cwd_backup = os.getcwd()
|
|
85 |
if dom.startswith('file:///') or dom.startswith('///') or os.path.exists(dom):
|
|
86 |
try:
|
|
87 |
path = urllib.url2pathname(dom)
|
|
88 |
path = path.replace('file:///', '')
|
|
89 |
os.chdir(os.path.dirname(path))
|
|
90 |
except IOError:
|
|
91 |
pass
|
587
|
92 |
dom = urllib.urlopen(dom).read()
|
628
|
93 |
|
|
94 |
ettree = xml.etree.ElementTree.fromstring(dom)
|
|
95 |
xml.etree.ElementInclude.include(ettree)
|
|
96 |
dom = xml.etree.ElementTree.tostring(ettree)
|
|
97 |
os.chdir(cwd_backup)
|
587
|
98 |
self.dom = xml.dom.minidom.parseString(dom)
|
|
99 |
else:
|
|
100 |
self.dom = dom
|
|
101 |
|
|
102 |
def __getitem__(self, name):
|
|
103 |
return self.__getattr__(name)
|
628
|
104 |
|
|
105 |
def __setitem__(self, key, value):
|
|
106 |
self.xml_set_attribute(key, value)
|
|
107 |
|
645
|
108 |
def __getattr__(self, attr):
|
|
109 |
if attr == 'xml_child_elements':
|
|
110 |
return self._getxml_child_elements()
|
587
|
111 |
if isinstance(attr, basestring):
|
|
112 |
res = self.dom.getElementsByTagName(attr)
|
|
113 |
if len(res) == 0:
|
|
114 |
if hasattr(self.dom, 'documentElement'):
|
|
115 |
val = self.dom.documentElement.getAttribute(attr)
|
628
|
116 |
if not self.dom.documentElement.hasAttribute(attr):
|
645
|
117 |
raise AttributeError(attr + ' not found')
|
587
|
118 |
else:
|
|
119 |
val = self.dom.getAttribute(attr)
|
628
|
120 |
if not self.dom.hasAttribute(attr):
|
645
|
121 |
raise AttributeError(attr + ' not found')
|
587
|
122 |
return val
|
|
123 |
return MinidomAmara(res[0], self.dom)
|
628
|
124 |
if self.parent:
|
|
125 |
return MinidomAmara(self.parent.getElementsByTagName(self.dom.tagName)[attr])
|
|
126 |
else:
|
645
|
127 |
raise AttributeError(str(attr) + ' not found')
|
587
|
128 |
|
628
|
129 |
def __setattr__(self, name, value):
|
|
130 |
if isinstance(value, basestring):
|
|
131 |
self.xml_set_attribute(name, value)
|
|
132 |
else:
|
|
133 |
object.__setattr__(self, name, value)
|
|
134 |
|
587
|
135 |
def __iter__(self):
|
|
136 |
for entry in self.parent.getElementsByTagName(self.dom.tagName):
|
|
137 |
yield MinidomAmara(entry)
|
|
138 |
|
645
|
139 |
def _get_text(self, node):
|
|
140 |
""" Recursive method to collate sub-node strings. """
|
587
|
141 |
text = ''
|
645
|
142 |
for child in node.childNodes:
|
|
143 |
if child.nodeType == child.TEXT_NODE and child.data != None:
|
|
144 |
text = text + ' ' + child.data
|
|
145 |
else:
|
|
146 |
text += self._get_text(child)
|
|
147 |
return text.strip()
|
587
|
148 |
|
645
|
149 |
def __str__(self):
|
|
150 |
""" Output a string representing the XML node. """
|
|
151 |
return self._get_text(self.dom)
|
|
152 |
|
628
|
153 |
def xml(self, out=None, indent=False, omitXmlDeclaration=False, encoding='utf-8'):
|
587
|
154 |
"""xml"""
|
628
|
155 |
if omitXmlDeclaration:
|
|
156 |
pass
|
587
|
157 |
if out:
|
628
|
158 |
out.write(self.dom.toprettyxml(encoding=encoding))
|
587
|
159 |
if indent:
|
628
|
160 |
return self.dom.toprettyxml(encoding=encoding)
|
|
161 |
return self.dom.toxml(encoding=encoding)
|
587
|
162 |
|
|
163 |
def xml_append_fragment(self, text):
|
|
164 |
"""xml append fragment"""
|
|
165 |
self.dom.appendChild(xml.dom.minidom.parseString(text).documentElement)
|
|
166 |
|
|
167 |
def xml_set_attribute(self, name, value):
|
|
168 |
"""set XML attribute"""
|
|
169 |
self.dom.setAttribute(name, value)
|
|
170 |
|
628
|
171 |
def xml_remove_child(self, value):
|
|
172 |
self.dom.removeChild(value.dom)
|
|
173 |
|
587
|
174 |
def _getxml_children(self):
|
|
175 |
"""get xml children"""
|
|
176 |
l_attrib = []
|
|
177 |
for elem in self.dom.childNodes:
|
|
178 |
if elem.nodeType == elem.ELEMENT_NODE:
|
|
179 |
l_attrib.append(MinidomAmara(elem))
|
|
180 |
return l_attrib
|
645
|
181 |
|
|
182 |
def _getxml_child_elements(self):
|
|
183 |
"""get xml children"""
|
|
184 |
l_attrib = {}
|
|
185 |
for elem in self.dom.childNodes:
|
|
186 |
if elem.nodeType == elem.ELEMENT_NODE:
|
|
187 |
l_attrib[elem.tagName] = MinidomAmara(elem)
|
|
188 |
return l_attrib
|
587
|
189 |
|
|
190 |
def _getxml_attributes(self):
|
|
191 |
"""get aml attributes"""
|
|
192 |
l_attrib = self.dom.attributes
|
|
193 |
out = {}
|
|
194 |
for i in range(l_attrib.length):
|
|
195 |
out[l_attrib.item(i).name] = l_attrib.item(i).nodeValue
|
|
196 |
return out
|
|
197 |
|
|
198 |
def xml_append(self, value):
|
|
199 |
"""append to XML """
|
|
200 |
if hasattr(self.dom, 'documentElement') and self.dom.documentElement != None:
|
|
201 |
value.dom.documentElement = self.dom.documentElement.appendChild(value.dom.documentElement)
|
|
202 |
else:
|
|
203 |
value.dom.documentElement = self.dom.appendChild(value.dom.documentElement)
|
|
204 |
|
|
205 |
def xml_create_element(self, name, content=None, attributes=None):
|
|
206 |
""" create XML element"""
|
|
207 |
elem = create_document(name)
|
|
208 |
if attributes:
|
|
209 |
for attrib in attributes.keys():
|
|
210 |
elem[name].dom.setAttribute(attrib, attributes[attrib])
|
|
211 |
if content:
|
|
212 |
impl = xml.dom.minidom.getDOMImplementation()
|
|
213 |
newdoc = impl.createDocument(None, None, None)
|
|
214 |
elem[name].dom.appendChild(newdoc.createTextNode(content))
|
|
215 |
return elem
|
|
216 |
|
|
217 |
def _getnodetype(self):
|
|
218 |
"""get node type"""
|
|
219 |
return self.dom.nodeType
|
|
220 |
def _getnodename(self):
|
|
221 |
"""get node nmae"""
|
|
222 |
return self.dom.nodeName
|
|
223 |
|
|
224 |
nodeType = property(_getnodetype)
|
|
225 |
nodeName = property(_getnodename)
|
|
226 |
childNodes = property(_getxml_children)
|
|
227 |
xml_children = property(_getxml_children)
|
|
228 |
xml_attributes = property(_getxml_attributes)
|
645
|
229 |
xml_child_elements = property(_getxml_child_elements)
|
587
|
230 |
|
|
231 |
def __eq__(self, obj):
|
|
232 |
return str(self) == obj
|
628
|
233 |
def __ne__(self, obj):
|
|
234 |
return str(self) != obj
|
587
|
235 |
|
|
236 |
def __len__(self):
|
628
|
237 |
if self.parent:
|
|
238 |
return len(self.parent.getElementsByTagName(self.dom.tagName))
|
|
239 |
return 1
|
587
|
240 |
|
628
|
241 |
def xml_xpath(self, axpath):
|
587
|
242 |
"""append to the XML path"""
|
628
|
243 |
results = []
|
|
244 |
for result in xpath.find(axpath, self.dom):
|
|
245 |
results.append(MinidomAmara(result))
|
|
246 |
return results
|
|
247 |
# import java.io.ByteArrayInputStream
|
|
248 |
# import org.dom4j.io.SAXReader
|
|
249 |
# import org.dom4j.DocumentHelper
|
|
250 |
#
|
|
251 |
# stream = java.io.ByteArrayInputStream(java.lang.String(self.dom.toxml()).getBytes("UTF-8"))
|
|
252 |
# xmlReader = org.dom4j.io.SAXReader()
|
|
253 |
# doc = xmlReader.read(stream)
|
|
254 |
# xpath = org.dom4j.DocumentHelper.createXPath(xpath)
|
|
255 |
# signalNodes = xpath.selectNodes(doc)
|
|
256 |
# iterator = signalNodes.iterator()
|
|
257 |
# out = []
|
|
258 |
# while iterator.hasNext():
|
|
259 |
# p_iterator = iterator.next()
|
|
260 |
# out.append(MinidomAmara(p_iterator.asXML()))
|
|
261 |
# return out
|