summaryrefslogtreecommitdiff
path: root/rdflib/plugins/serializers/xmlwriter.py
diff options
context:
space:
mode:
authoreikeon <devnull@localhost>2010-02-13 01:54:03 +0000
committereikeon <devnull@localhost>2010-02-13 01:54:03 +0000
commit0ffb306d0576461a51062a17e7cc90cad78187b7 (patch)
tree98545fe15341706c89fa05a88a0c583cd98fc54a /rdflib/plugins/serializers/xmlwriter.py
parent02b60fa0002fd2efd8a245265f0a8fce1122affd (diff)
downloadrdflib-0ffb306d0576461a51062a17e7cc90cad78187b7.tar.gz
Update issue 120
Moving parsers and serializer implementations into rdflib.plugins package
Diffstat (limited to 'rdflib/plugins/serializers/xmlwriter.py')
-rw-r--r--rdflib/plugins/serializers/xmlwriter.py102
1 files changed, 102 insertions, 0 deletions
diff --git a/rdflib/plugins/serializers/xmlwriter.py b/rdflib/plugins/serializers/xmlwriter.py
new file mode 100644
index 00000000..5d15f4b7
--- /dev/null
+++ b/rdflib/plugins/serializers/xmlwriter.py
@@ -0,0 +1,102 @@
+import codecs
+from xml.sax.saxutils import quoteattr, escape
+
+
+class XMLWriter(object):
+ def __init__(self, stream, namespace_manager, encoding=None, decl=1, extra_ns={}):
+ encoding = encoding or 'utf-8'
+ encoder, decoder, stream_reader, stream_writer = codecs.lookup(encoding)
+ self.stream = stream = stream_writer(stream)
+ if decl:
+ stream.write('<?xml version="1.0" encoding="%s"?>' % encoding)
+ self.element_stack = []
+ self.nm = namespace_manager
+ self.extra_ns=extra_ns
+ self.closed = True
+
+ def __get_indent(self):
+ return " " * len(self.element_stack)
+ indent = property(__get_indent)
+
+ def __close_start_tag(self):
+ if not self.closed: # TODO:
+ self.closed = True
+ self.stream.write(">")
+
+ def push(self, uri):
+ self.__close_start_tag()
+ write = self.stream.write
+ write("\n")
+ write(self.indent)
+ write("<%s" % self.qname(uri))
+ self.element_stack.append(uri)
+ self.closed = False
+ self.parent = False
+
+ def pop(self, uri=None):
+ top = self.element_stack.pop()
+ if uri:
+ assert uri == top
+ write = self.stream.write
+ if not self.closed:
+ self.closed = True
+ write("/>")
+ else:
+ if self.parent:
+ write("\n")
+ write(self.indent)
+ write("</%s>" % self.qname(top))
+ self.parent = True
+
+ def element(self, uri, content, attributes={}):
+ """Utility method for adding a complete simple element"""
+ self.push(uri)
+ for k, v in attributes.iteritems():
+ self.attribute(k,v)
+ self.text(content)
+ self.pop()
+
+ def namespaces(self, namespaces=None):
+ if not namespaces:
+ namespaces=self.nm.namespaces()
+
+ write = self.stream.write
+ write("\n")
+ for prefix, namespace in namespaces:
+ if prefix:
+ write(' xmlns:%s="%s"\n' % (prefix, namespace))
+ else:
+ write(' xmlns="%s"\n' % namespace)
+
+ for prefix, namespace in self.extra_ns.items():
+ if prefix:
+ write(' xmlns:%s="%s"\n' % (prefix, namespace))
+ else:
+ write(' xmlns="%s"\n' % namespace)
+
+
+ def attribute(self, uri, value):
+ write = self.stream.write
+ write(" %s=%s" % (self.qname(uri), quoteattr(value)))
+
+ def text(self, text):
+ self.__close_start_tag()
+ if "<" in text and ">" in text and not "]]>" in text:
+ self.stream.write("<![CDATA[")
+ self.stream.write(text)
+ self.stream.write("]]>")
+ else:
+ self.stream.write(escape(text))
+
+ def qname(self,uri):
+ """Compute qname for a uri using our extra namespaces,
+ or the given namespace manager"""
+
+ for pre,ns in self.extra_ns.items():
+ if uri.startswith(ns):
+ if pre!="":
+ return ":".join(pre,uri[len(ns):])
+ else:
+ return uri[len(ns):]
+
+ return self.nm.qname(uri)