xmlwitch icon indicating copy to clipboard operation
xmlwitch copied to clipboard

Incompatible with Python 3

Open borisdayma opened this issue 13 years ago • 5 comments

Hi,

The script doesn't wotk with python 3. I have tried 2to3 script and also modified some things manually but it still doesn't work.

If you know how to correct it could you please help me ?

Thanks

borisdayma avatar Apr 07 '11 19:04 borisdayma

The problem has been solved making some little modifications with the script .

I don't know how to let it compatible for both python 2/3...

############## script ##############

from io import StringIO from xml.sax import saxutils from keyword import kwlist as PYTHON_KWORD_LIST

all = ['Builder', 'Element'] license = 'BSD' version = '0.2.1' author = "Jonas Galvez http://jonasgalvez.com.br/" contributors = ["bbolli http://github.com/bbolli/", "masklinn http://github.com/masklinn/"]

class Builder:

def __init__(self, encoding='utf-8', indent=' '*2, version=None):
    self._document = StringIO()
    self._encoding = encoding
    self._indent = indent
    self._indentation = 0
    if version is not None:
        self.write('<?xml version="%s" encoding="%s"?>\n' % (
            version, encoding
        ))

def __getattr__(self, name):
    return Element(name, self)

def __getitem__(self, name):
    return Element(name, self)

def __str__(self):
    return self._document.getvalue().strip()

def write(self, content):
    """Write raw content to the document"""
    if type(content) is not str:
        content = content.decode(self._encoding)
    self._document.write('%s' % content)

def write_escaped(self, content):
    """Write escaped content to the document"""
    self.write(saxutils.escape(content))

def write_indented(self, content):
    """Write indented content to the document"""
    self.write('%s%s\n' % (self._indent * self._indentation, content))

builder = Builder # 0.1 backward compatibility

class Element:

PYTHON_KWORD_MAP = dict([(k + '_', k) for k in PYTHON_KWORD_LIST])

def __init__(self, name, builder):
    self.name = self._nameprep(name)
    self.builder = builder
    self.attributes = {}

def __enter__(self):
    """Add a parent element to the document"""
    self.builder.write_indented('<%s%s>' % (
        self.name, self._serialized_attrs()
    ))
    self.builder._indentation += 1
    return self

def __exit__(self, type, value, tb):
    """Add close tag to current parent element"""
    self.builder._indentation -= 1
    self.builder.write_indented('</%s>' % self.name)

def __call__(*args, **kargs):
    """Add a child element to the document"""
    self = args[0]
    self.attributes.update(kargs)
    if len(args) > 1:
        value = args[1]
        if value is None:
            self.builder.write_indented('<%s%s />' % (
                self.name, self._serialized_attrs()
            ))
        else:
            value = saxutils.escape(value)
            self.builder.write_indented('<%s%s>%s</%s>' % (
                self.name, self._serialized_attrs(), value, self.name
            ))
    return self

def _serialized_attrs(self):
    """Serialize attributes for element insertion"""
    serialized = []
    for attr, value in list(self.attributes.items()):
        serialized.append(' %s=%s' % (
            self._nameprep(attr), saxutils.quoteattr(value)
        ))
    return ''.join(serialized)

def _nameprep(self, name):
    """Undo keyword and colon mangling"""
    name = Element.PYTHON_KWORD_MAP.get(name, name)
    return name.replace('__', ':')

##################################

Boris Dayma

borisdayma avatar Apr 08 '11 17:04 borisdayma

Going to look into this as soon as I get a chance. Thanks.

galvez avatar Apr 11 '11 13:04 galvez

By the way, I don't know if it is normal but when you do not specify a text value, like

xml.calculation(Id = '1', name = 'standard')

Nothing will happen.

It will work only if there is a "with" statement or None value is passed :

       with xml.calculation(Id = '1', name = 'standard'):
           pass

OR

       xml.calculation(None, Id = '1', name = 'standard')

I have not succeeded in correcting it without having a problem with enter function The problem being that inside a with statement like with xml.calculation(Id = '1', name = 'standard') both enter and call functions could be called and only one is to be called.

If you have some idea can you tell me ? I was thinking of modifying "call" so as it runs only when not before a "enter" function by keeping in memory parameters and launching it only at next "call" time... But I have not succeeded.

Thanks

borisdayma avatar Apr 11 '11 20:04 borisdayma

Read the documentation at http://jonasgalvez.com.br/Software/XMLWitch.html

For creating empty elements, pass None as the first parameter.

galvez avatar Apr 13 '11 02:04 galvez

I mean, that is by design. This is the most elegant way I have found to use the same call definition without any major syntax disruption. But I welcome suggestions.

galvez avatar Apr 13 '11 02:04 galvez