# HG changeset patch
# User cmlenz
# Date 1170265007 0
# Node ID c199e9b958848d74651f0efdcf9635c8bc53c8a7
# Parent 68772732c89699caaa89df91ccd1dac7576adc94
Fix output of namespace declarations for namespace URLs appearing more than once in a stream. Thanks to Jeff Cutsinger for reporting the problem.
diff --git a/genshi/output.py b/genshi/output.py
--- a/genshi/output.py
+++ b/genshi/output.py
@@ -23,8 +23,8 @@
import re
from genshi.core import escape, Markup, Namespace, QName, StreamEventKind
-from genshi.core import DOCTYPE, START, END, START_NS, TEXT, START_CDATA, \
- END_CDATA, PI, COMMENT, XML_NAMESPACE
+from genshi.core import DOCTYPE, START, END, START_NS, END_NS, TEXT, \
+ START_CDATA, END_CDATA, PI, COMMENT, XML_NAMESPACE
__all__ = ['DocType', 'XMLSerializer', 'XHTMLSerializer', 'HTMLSerializer',
'TextSerializer']
@@ -75,7 +75,7 @@
def __call__(self, stream):
ns_attrib = []
- ns_mapping = {XML_NAMESPACE.uri: 'xml'}
+ ns_mapping = {XML_NAMESPACE.uri: ['xml']}
have_doctype = False
in_cdata = False
@@ -88,14 +88,14 @@
tag, attrib = data
tagname = tag.localname
- namespace = tag.namespace
- if namespace:
- if namespace in ns_mapping:
- prefix = ns_mapping[namespace]
- if prefix:
- tagname = '%s:%s' % (prefix, tagname)
+ tagns = tag.namespace
+ if tagns:
+ if tagns in ns_mapping:
+ prefix = ns_mapping.get(tagns)
+ if prefix and prefix[-1]:
+ tagname = '%s:%s' % (prefix[-1], tagname)
else:
- ns_attrib.append((QName('xmlns'), namespace))
+ ns_attrib.append((QName('xmlns'), tagns))
buf = ['<', tagname]
if ns_attrib:
@@ -105,8 +105,8 @@
attrns = attr.namespace
if attrns:
prefix = ns_mapping.get(attrns)
- if prefix:
- attrname = '%s:%s' % (prefix, attrname)
+ if prefix and prefix[-1]:
+ attrname = '%s:%s' % (prefix[-1], attrname)
buf += [' ', attrname, '="', escape(value), '"']
ns_attrib = []
@@ -119,8 +119,8 @@
tagname = tag.localname
if tag.namespace:
prefix = ns_mapping.get(tag.namespace)
- if prefix:
- tagname = '%s:%s' % (prefix, tag.localname)
+ if prefix and prefix[-1]:
+ tagname = '%s:%s' % (prefix[-1], tagname)
yield Markup('%s>' % tagname)
elif kind is TEXT:
@@ -148,11 +148,18 @@
elif kind is START_NS:
prefix, uri = data
if uri not in ns_mapping:
- ns_mapping[uri] = prefix
if not prefix:
ns_attrib.append((QName('xmlns'), uri))
else:
ns_attrib.append((QName('xmlns:%s' % prefix), uri))
+ ns_mapping.setdefault(uri, []).append(prefix)
+
+ elif kind is END_NS:
+ for uri, prefix in ns_mapping.items():
+ if prefix[-1] == data:
+ prefix.pop()
+ if not prefix:
+ del ns_mapping[uri]
elif kind is START_CDATA:
yield Markup('' % tagname)
elif kind is TEXT:
@@ -277,11 +284,18 @@
elif kind is START_NS:
prefix, uri = data
if uri not in ns_mapping:
- ns_mapping[uri] = prefix
if not prefix:
ns_attrib.append((QName('xmlns'), uri))
else:
ns_attrib.append((QName('xmlns:%s' % prefix), uri))
+ ns_mapping.setdefault(uri, []).append(prefix)
+
+ elif kind is END_NS:
+ for uri, prefix in ns_mapping.items():
+ if prefix[-1] == data:
+ prefix.pop()
+ if not prefix:
+ del ns_mapping[uri]
elif kind is START_CDATA:
yield Markup('
+