2010-10-28 12 views
2

J'essaye d'écrire un script python qui prend en un ou deux fichiers xml et sort un ou deux nouveaux fichiers basés sur le contenu des fichiers d'entrée. J'essayais d'écrire ce script en utilisant le module minidom. Cependant, les fichiers d'entrée contiennent un certain nombre d'instances du caractère d'échappementPréservation des caractères échappés dans l'analyse XML Python

à l'intérieur des attributs de nœud. Malheureusement, dans les fichiers de sortie, ces caractères ont été convertis en caractères différents, qui semblent être des caractères de nouvelle ligne.

Par exemple, une ligne dans le fichier d'entrée tels que:

<Entry text="For English For Hearing Impaired&#xa;Press 3 on Keypad" 

Serait sortie comme

<Entry text="For English For Hearing Impaired 
Press 3 on Keypad" 

J'ai lu que minidom cause cela, car elle ne permet pas de caractères d'échappement dans les attributs XML (je pense). Est-ce vrai? Et, si c'est le cas, quel est le meilleur outil/méthode à utiliser pour analyser un fichier xml dans un document python, manipuler des nœuds et les échanger avec d'autres documents, et renvoyer les documents dans de nouveaux fichiers?

Si ça aide, j'ai aussi analysé et sauvegardé ces fichiers en utilisant le codage 'utf-8'. Je ne sais pas si cela fait partie du problème ou non. Merci pour toute aide que quelqu'un peut vous donner.

-Alex Kaiser

Répondre

4

Je n'ai pas utilisé les modules XML standard de Python depuis la découverte lxml. Il peut faire tout ce que vous cherchez. Par exemple ...

input.xml:

<?xml version="1.0" encoding='utf-8'?> 
<root> 
    <Button3 yposition="250" fontsize="16" language1="For English For Hearing Impaired&#xa;Press 3 on Keypad" /> 
</root> 

et:

>>> from lxml import etree 
>>> with open('input.xml') as f: 
...  root = etree.parse(f) 
... 
>>> buttons = root.xpath('//Button3') 
>>> buttons 
[<Element Button3 at 101071f18>] 
>>> buttons[0] 
<Element Button3 at 101071f18> 
>>> buttons[0].attrib 
{'yposition': '250', 'language1': 'For English For Hearing Impaired\nPress 3 on Keypad', 'fontsize': '16'} 
>>> buttons[0].attrib['foo'] = 'bar' 
>>> s = etree.tostring(root, xml_declaration=True, encoding='utf-8', pretty_print=True) 
>>> print(s) 
<?xml version='1.0' encoding='utf-8'?> 
<root> 
    <Button3 yposition="250" fontsize="16" language1="For English For Hearing Impaired&#10;Press 3 on Keypad" foo="bar"/> 
</root> 
>>> with open('output.xml','w') as f: 
...  f.write(s) 
>>> 
0

&#xa; est l'entité XML pour le caractère 0x0a, ou un saut de ligne. L'analyseur syntaxique analyse correctement le code XML et vous donne les caractères indiqués. Si vous souhaitez interdire ou traiter les nouvelles lignes dans les attributs, vous êtes libre de faire ce que vous voulez avec eux après que l'analyseur vous les ait données.

0

Malheureusement, le module standard xml n'a pas l'option de désactiver l'échappement. Donc, pour moi la meilleure option était de escape it back en utilisant la méthode de ElementTree qui est utilisé par xml lui-même à cet effet (méthode de sax.utils n'échappe pas \n):

text = ElementTree._escape_attrib(text, 'utf-8') 

texte en XML source:

Here is a test message&#10;With newline &amp; ampersand 

texte après "décodage":

Here is a test message 
With newline & ampersand 

texte après "retour échapper":

Here is a test message&#10;With newline &amp; ampersand