2010-03-22 6 views
0

J'essaie d'analyser un fichier XML (données OSM) avec expat, et il y a des lignes avec des caractères Unicode expat ne peut pas analyser:Python.expat ne peut pas analyser le fichier XML avec de mauvais symboles. Comment faire le tour?

<tag k="name" 
v="абвгдежзиклмнопр�?туфхцчшщьыъ�?ю�?�?БВГДЕЖЗИКЛМ�?ОПРСТУФХЦЧШЩЬЫЪЭЮЯ" /> 

<tag k="name" v="Cin\x8e? Rex" /> 

(fichier XML de codage dans la ligne d'ouverture est " UTF-8 ")

Le fichier est assez ancien et il doit y avoir eu des erreurs. Dans les fichiers modernes, je ne vois pas d'erreurs UTF-8, et ils sont bien analysés. Mais que faire si mon programme rencontre un symbole brisé, quelle solution de contournement puis-je faire? Est-il possible de joindre le codec bz2 (j'analyse un fichier compressé) et le codec utf-8 pour ignorer les caractères brisés, ou les changer en "?"?

+0

Qu'est-ce que le codage

+0

Semble comme un jeu de caractères problème – Andy

Répondre

1

Je ne sais pas si « » caractères ont été introduits par la chaîne du copier-coller ici, mais si vous les avez dans les données d'origine, il semble être générateur problème qui introduit \ uFFFD charactes comme:

" utilisé pour remplacer un caractère entrant dont la valeur est inconnue ou irreprésentable en Unicode »

citied de: http://www.fileformat.info/info/unicode/char/fffd/index.htm

Solution? Idée juste pour l'extension:

good = True 
buf = None 
while True: 
if good: 
     buf = f.read(buf_size) 
     else: 
     # try again with cleaned buffer 
     pass 
     try: 
      xp.Parse(buf, len(buf) == 0) 
      if (len(buf) == 0): 
        break 
     good = True 
    except ExpatError: 
     if xp.ErrorCode == XML_ERROR_BAD_CHAR_REF: 
      # look at ErrorByteIndex (or nearby) 
      # for 0xEF 0xBF 0xBD (UTF8 replacement char) and remove it 
      good = False 
     else: 
      # other errors processing 
      pass 

Ou nettoyer le tampon d'entrée à la place + les cas d'angle (séquence partielle à l'extrémité du tampon). Je ne me souviens pas si l'expat de python permet d'assigner un gestionnaire d'erreur personnalisé. Ce serait plus facile alors.

Si je nettoie votre échantillon à partir des caractères ' ', il est traité correctement. \ xd1 n'échoue pas.

Données OSM?

+0

Oui, c'est OSM décharge de la terre entière. Je vais essayer de faire un générateur de code, merci! –

+0

J'ai noté que xp.ErrorCode contient un code numérique, mais XML_ERROR_BAD_CHAR_REF contient une chaîne (Python 2.6). C'est un vrai casse-tête si je veux vérifier le type d'erreur: je vais devoir comparer les chaînes, etc. –

+0

Eh bien ... ça ne marche pas: quand expat soulève une erreur, il a déjà mangé les caractères, et Je n'arrive pas à trouver un moyen d'obtenir l'index du mauvais caractère dans 'buf'. Il n'y a que 'lineno' et' columnno', et le compteur de caractères compte _all_ caractères dans le fichier, mais pas dans 'buf'. –