This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: XMLGenerator.startElementNS dies on EMPTY_NAMESPACE attribut
Type: Stage:
Components: XML Versions: Python 2.3
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: akuchling, loewis, ngrig, zenzen
Priority: normal Keywords:

Created on 2003-11-23 15:21 by zenzen, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
startElementNS.py zenzen, 2003-11-24 19:44 Replacement startElementNS and endElementNS
Messages (7)
msg19095 - (view) Author: Stuart Bishop (zenzen) Date: 2003-11-23 15:21
from xml.sax.saxutils import XMLGenerator

g = XMLGenerator(encoding='utf8')
STREAM_NAMESPACE = 'http://etherx.jabber.org/streams'
CLIENT_NAMESPACE = 'jabber:client'
g.startDocument()
g.startPrefixMapping('stream', STREAM_NAMESPACE)
g.startPrefixMapping('client', CLIENT_NAMESPACE)
g.startElementNS( 
    (STREAM_NAMESPACE, 'stream'), 'stream',
    {(None,'xmlns'): CLIENT_NAMESPACE}
    )

Dies with:
Traceback (most recent call last):
  File "tst.py", line 11, in ?
    g.startElementNS( 
  File "/System/Library/Frameworks/Python.framework/
Versions/2.3/lib/python2.3/xml/sax/saxutils.py", line 124, in 
startElementNS
    name = self._current_context[name[0]] + ":" + name[1]
KeyError: 'x'


Changing the end of XMLGenerator.startElementNS to the 
following makes it work the way I expect:

        for (name, value) in attrs.items():
            if name[0] is None:
                name = name[1]
            else:
                name = self._current_context[name[0]] + ":" + 
name[1]
            self._out.write(' %s=%s' % (name, 
quoteattr(value)))
        self._out.write('>')
msg19096 - (view) Author: Stuart Bishop (zenzen) Date: 2003-11-24 19:36
Logged In: YES 
user_id=46639

This method also appears to have trouble emmitting tags without a 
namespace prefix:

import xml.sax
import xml.sax.handler
import xml.sax.saxutils
x = '''<?xml version="1.0"?><mechanisms xmlns='urn:ietf:
params:xml:ns:xmpp-sasl'
>'''
parser = xml.sax.make_parser()
parser.setFeature(xml.sax.handler.feature_namespaces, True)
parser.setContentHandler(xml.sax.saxutils.XMLGenerator())
parser.feed(x)

dies with:
Traceback (most recent call last):
  File "tst.py", line 30, in ?
    parser.feed(x)
  File "/System/Library/Frameworks/Python.framework/Versions/
2.3/lib/python2.3/xml/sax/expatreader.py", line 207, in feed
    self._parser.Parse(data, isFinal)
  File "/System/Library/Frameworks/Python.framework/Versions/
2.3/lib/python2.3/xml/sax/expatreader.py", line 337, in 
start_element_ns
    AttributesNSImpl(newattrs, qnames))
  File "/System/Library/Frameworks/Python.framework/Versions/
2.3/lib/python2.3/xml/sax/saxutils.py", line 116, in startElementNS
    name = self._current_context[name[0]] + ":" + name[1]
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'



I've attached my current replacement startElementNS method 
which appears to fix both this and the previous issue.
msg19097 - (view) Author: A.M. Kuchling (akuchling) * (Python committer) Date: 2005-12-04 20:01
Logged In: YES 
user_id=11375

I don't understand your second example; it uses saxutils to
parse a file.  What's it got to do with XMLGenerator?
msg19098 - (view) Author: A.M. Kuchling (akuchling) * (Python committer) Date: 2005-12-04 20:02
Logged In: YES 
user_id=11375

Never mind my previous comment; I just noticed the
setContentHandler call.
msg19099 - (view) Author: A.M. Kuchling (akuchling) * (Python committer) Date: 2005-12-04 20:15
Logged In: YES 
user_id=11375

Please provide your changes in the form of a patch.
msg19100 - (view) Author: Nikolai Grigoriev (ngrig) Date: 2006-03-26 21:29
Logged In: YES 
user_id=195108

This issue lasts for 2.5 years already. I feel like it is
somewhat stalled.

The processing of XML namespaces in saxutils.XMLGenerator is
so blatantly broken that I wonder if it ever has been tested
at all. I wrote down a simple smoke test for it:


import sys
from xml import sax
from xml.sax.saxutils import XMLGenerator
from StringIO import StringIO

tests = [
("No namespace, no attributes",     "<a/>"),
("No namespace, with attributes",   "<a b='c'/>"),
("Empty prefix, no attributes",     "<a xmlns='qux'/>"),
("Empty prefix, unprefixed attributes", "<a xmlns='qux'
b='c'/>"),
("Prefixed, no attributes",         "<my:a xmlns:my='qux'/>"),
("Prefixed, unprefixed attributes", "<my:a xmlns:my='qux'
b='c'/>"),               
("Prefixed, prefixed attributes",   "<my:a xmlns:my='qux'
my:b='c'/>"),
]
          
for (caption, testdoc) in tests:
    try:
        parser = sax.make_parser()
        parser.setFeature(sax.handler.feature_namespaces, 1)
        parser.setContentHandler(XMLGenerator(StringIO()))
        parser.parse(StringIO(testdoc))
        print caption, "- OK"
    except StandardError, e:
        print caption, "- FAILED:", e.__class__.__name__


With the current version of saxutils (as of Python 2.4.1), I
get 4 failures out of 7. Stuart Bishop's patch fixes the
issue; could someone commit it please?
msg19101 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2007-02-12 12:23
This is now fixed in r53754 and r53755.
History
Date User Action Args
2022-04-11 14:56:01adminsetgithub: 39586
2003-11-23 15:21:36zenzencreate