add "is_available" function to all version control modules
[translate_toolkit.git] / misc / xmlwrapper.py
blob96cfc9516c5cbed485440b7fa2780eb99d18d328
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 #
4 # Copyright 2004, 2005 Zuza Software Foundation
5 #
6 # This file is part of translate.
8 # translate is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
13 # translate is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with translate; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 """simpler wrapper to the elementtree XML parser"""
24 try:
25 from xml.etree import ElementTree
26 except ImportError:
27 from elementtree import ElementTree
28 # this is needed to prevent expat-version conflicts with wx >= 2.5.2.2
29 from xml.parsers import expat
31 basicfixtag = ElementTree.fixtag
33 def makefixtagproc(namespacemap):
34 """this constructs an alternative fixtag procedure that will use appropriate names for namespaces..."""
35 def fixtag(tag, namespaces):
36 """given a decorated tag (of the form {uri}tag), return prefixed tag and namespace declaration, if any"""
37 if isinstance(tag, ElementTree.QName):
38 tag = tag.text
39 namespace_uri, tag = tag[1:].split("}", 1)
40 prefix = namespaces.get(namespace_uri)
41 if prefix is None:
42 if namespace_uri in namespacemap:
43 prefix = namespacemap[namespace_uri]
44 else:
45 prefix = "ns%d" % len(namespaces)
46 namespaces[namespace_uri] = prefix
47 xmlns = ("xmlns:%s" % prefix, namespace_uri)
48 else:
49 xmlns = None
50 return "%s:%s" % (prefix, tag), xmlns
51 return fixtag
53 def splitnamespace(fulltag):
54 if '{' in fulltag:
55 namespace = fulltag[fulltag.find('{'):fulltag.find('}')+1]
56 else:
57 namespace = ""
58 tag = fulltag.replace(namespace, "", 1)
59 return namespace, tag
61 class XMLWrapper:
62 """simple wrapper for xml objects"""
63 def __init__(self,obj):
64 """construct object from the elementtree item"""
65 self.obj = obj
66 self.namespace, self.tag = splitnamespace(self.obj.tag)
67 self.attrib = {}
68 for fullkey, value in self.obj.attrib.iteritems():
69 namespace, key = splitnamespace(fullkey)
70 self.attrib[key] = value
71 def getchild(self, searchtag, tagclass=None):
72 """get a child with the given tag name"""
73 if tagclass is None: tagclass = XMLWrapper
74 for childobj in self.obj.getiterator():
75 # getiterator() includes self...
76 if childobj == self.obj: continue
77 childns, childtag = splitnamespace(childobj.tag)
78 if childtag == searchtag:
79 child = tagclass(childobj)
80 return child
81 raise KeyError("could not find child with tag %r" % searchtag)
82 def getchildren(self, searchtag, tagclass=None, excludetags=[]):
83 """get all children with the given tag name"""
84 if tagclass is None: tagclass = XMLWrapper
85 childobjects = []
86 for childobj in self.obj.getiterator():
87 # getiterator() includes self...
88 if childobj == self.obj: continue
89 childns, childtag = splitnamespace(childobj.tag)
90 if childtag == searchtag:
91 childobjects.append(childobj)
92 children = [tagclass(childobj) for childobj in childobjects]
93 return children
94 def gettext(self, searchtag):
95 """get some contained text"""
96 return self.getchild(searchtag).obj.text
97 def getxml(self, encoding=None):
98 return ElementTree.tostring(self.obj, encoding)
99 def getplaintext(self, excludetags=[]):
100 text = ""
101 if self.obj.text != None: text += self.obj.text
102 for child in self.obj._children:
103 simplechild = XMLWrapper(child)
104 if simplechild.tag not in excludetags:
105 text += simplechild.getplaintext(excludetags)
106 if self.obj.tail != None: text += self.obj.tail
107 return text
108 def getvalues(self, searchtag):
109 """get some contained values..."""
110 values = [child.obj.text for child in self.getchildren(searchtag)]
111 return values
112 def __repr__(self):
113 """return a representation of the object"""
114 return self.tag+':'+repr(self.__dict__)
115 def getattr(self, attrname):
116 """gets an attribute of the tag"""
117 return self.attrib[attrname]
118 def write(self, file, encoding="UTF-8"):
119 """writes the object as XML to a file..."""
120 e = ElementTree.ElementTree(self.obj)
121 e.write(file, encoding)
123 def BuildTree(xmlstring):
124 parser = ElementTree.XMLTreeBuilder()
125 parser.feed(xmlstring)
126 return parser.close()
128 def MakeElement(tag, attrib={}, **extraargs):
129 return ElementTree.Element(tag, attrib, **extraargs)