2017-02-27 1 views
2

Vous avez un problème avec la génération d'un fichier .SVG avec Python3 et ElementTree.ElementTree TypeError "l'argument write() doit être str, pas bytes" dans Python3

from xml.etree import ElementTree as et 
    doc = et.Element('svg', width='480', height='360', version='1.1', xmlns='http://www.w3.org/2000/svg') 

    #Doing things with et and doc 

    f = open('sample.svg', 'w') 
    f.write('<?xml version=\"1.0\" standalone=\"no\"?>\n') 
    f.write('<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n') 
    f.write('\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n') 
    f.write(et.tostring(doc)) 
    f.close() 

Le et.tostring Function (doc) génère le TypeError "argument write() doit être str, pas d'octets". Je ne comprends pas ce comportement, "et" devrait convertir l'ElementTree-Element en une chaîne? Cela fonctionne dans python2, mais pas dans python3. Qu'ai-je fait de mal?

+0

Avez-vous vérifié la documentation? Voir [cette page] (https://docs.python.org/3/library/xml.etree.elementtree.html) et rechercher 'tostring'. Est ce que ça aide? –

+0

pas vraiment, il devrait être déjà décodé en utf-8 bytestring, mais python3 semble avoir un problème avec cela –

Répondre

6

Comme il se trouve, tostring, malgré son nom, vraiment -t retourne un objet dont le type est bytes.

Des choses plus étranges sont arrivées. Quoi qu'il en soit, voici la preuve:

>>> from xml.etree.ElementTree import ElementTree, tostring 
>>> import xml.etree.ElementTree as ET 
>>> element = ET.fromstring("<a></a>") 
>>> type(tostring(element)) 
<class 'bytes'> 

Idiot, n'est-ce pas?

Heureusement, vous pouvez le faire:

>>> type(tostring(element, encoding="unicode")) 
<class 'str'> 

Oui, nous avons tous pensé que le ridicule d'octets et que l'ancienne, l'encodage quarante-plus ans et obsolète appelé ascii était mort.

Et ne me lancez pas sur le fait qu'ils appellent "unicode" un codage !!!!!!!!!!!

+0

C'était amusant de tester. Je ne pouvais pas le croire quand j'ai vu le résultat de 'type (tostring (element))'. Et puis voir le résultat changer en raison d'un changement à une valeur de paramètre. Sensationnel. C'était vraiment bizarre. Bonne question. –

2

Essayez:

f.write(et.tostring(doc).decode(encoding)) 

Exemple:

f.write(et.tostring(doc).decode("utf-8")) 
2

Spécifiez le codage de la chaîne lors de l'écriture du fichier xml.

Comme decode(UTF-8) avec write(). Exemple: file.write(etree.tostring(doc).decode(UTF-8))