1 #!/usr/bin/env python 2 3 """ 4 A list of tuples to XML document converter. 5 6 Copyright (C) 2005 Paul Boddie <paul@boddie.org.uk> 7 8 This program is free software; you can redistribute it and/or modify it under 9 the terms of the GNU Lesser General Public License as published by the Free 10 Software Foundation; either version 3 of the License, or (at your option) any 11 later version. 12 13 This program is distributed in the hope that it will be useful, but WITHOUT 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 16 details. 17 18 You should have received a copy of the GNU Lesser General Public License along 19 with this program. If not, see <http://www.gnu.org/licenses/>. 20 """ 21 22 import libxml2dom 23 from UserDict import UserDict 24 25 class OrderedDict(UserDict): 26 27 "A dictionary with keys in the order in which they were given." 28 29 def __init__(self, *args): 30 UserDict.__init__(self, *args) 31 self._keys = self.data.keys() 32 33 def __setitem__(self, key, value): 34 UserDict.__setitem__(self, key, value) 35 if key not in self._keys: 36 self._keys.append(key) 37 38 def __delitem__(self, key): 39 UserDict.__delitem__(self, key) 40 del self._keys[key] 41 42 def keys(self): 43 return self._keys 44 45 def items(self): 46 l = [] 47 for key in self._keys: 48 l.append((key, self.data[key])) 49 return l 50 51 def values(self): 52 return [value for key, value in self.items()] 53 54 class Converter: 55 def __init__(self, ns=None, prefix="", doc=None, root=None): 56 self.ns = ns 57 self.prefix = prefix 58 if doc is not None: 59 self.doc = doc 60 else: 61 self.doc = libxml2dom.createDocument(ns, prefix+"table", None) 62 if root is not None: 63 self.root = root 64 else: 65 self.root = self.doc.xpath("*")[0] 66 67 # Remember the last row element. 68 69 self.last_row_element = None 70 71 def add_rows(self, rows): 72 for row in rows: 73 self.add_row(row) 74 75 def add_row(self, row, index=-1, row_element_name="row", use_key_as_element_name=0): 76 self.last_row_element = self.doc.createElementNS(self.ns, self.prefix+row_element_name) 77 if index == -1: 78 self.root.appendChild(self.last_row_element) 79 else: 80 self.root.insertBefore(self.last_row_element, self.root.xpath("*[%s]" % (index + 1))[0]) 81 82 # Permit dictionaries. 83 84 if hasattr(row, "items"): 85 for name, value in row.items(): 86 if use_key_as_element_name: 87 column_element = self.doc.createElementNS(self.ns, self.prefix+unicode(name)) 88 else: 89 column_element = self.doc.createElementNS(self.ns, self.prefix+"column") 90 column_element.setAttributeNS(self.ns, self.prefix+"name", unicode(name)) 91 self.last_row_element.appendChild(column_element) 92 text = self.doc.createTextNode(unicode(value)) 93 column_element.appendChild(text) 94 95 # As well as sequences. 96 97 else: 98 for column in row: 99 column_element = self.doc.createElementNS(self.ns, self.prefix+"column") 100 self.last_row_element.appendChild(column_element) 101 text = self.doc.createTextNode(unicode(column)) 102 column_element.appendChild(text) 103 104 def last_row(self): 105 if self.last_row_element is not None: 106 return Converter(self.ns, self.prefix, self.doc, self.last_row_element) 107 else: 108 return None 109 110 if __name__ == "__main__": 111 from rdflib.TripleStore import TripleStore 112 import sys 113 s = TripleStore() 114 s.load(sys.argv[1]) 115 converter = Converter() 116 converter.add_rows(s.triples((None, None, None))) 117 libxml2dom.toStream(converter.doc, sys.stdout) 118 119 # vim: tabstop=4 expandtab shiftwidth=4