se expat à utiliser .dtd pour le remplacement de l'entité en python
-
04-10-2019 - |
Question
Je suis en train de lire dans un fichier xml qui ressemble à ceci
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE dblp SYSTEM "dblp.dtd">
<dblp>
<incollection>
<author>José A. Blakeley</author>
</incollection>
</dblp>
Le point qui crée l'apparence de problème est le
José A. Blakeley
partie: L'analyseur appelle son gestionnaire de caractères deux fois, une fois avec « Jos », une fois avec « A. Blakeley ». Maintenant, je comprends cela peut être le comportement correct si elle ne connaît pas l'entité eacute. Cependant, cela est défini dans le dblp.dtd, que j'ai. Je ne semble pas être en mesure de convaincre expat d'utiliser ce fichier, cependant. Tout ce que je peux dire est
p = xml.parsers.expat.ParserCreate()
# tried with and without following line
p.SetParamEntityParsing(xml.parsers.expat.XML_PARAM_ENTITY_PARSING_ALWAYS)
p.UseForeignDTD(True)
f = open(dblp_file, "r")
p.ParseFile(f)
mais expat ne reconnaît toujours pas mon entité. Pourquoi est-il aucun moyen de dire expat qui DTD à utiliser? J'ai essayé
- mettre le fichier dans le même répertoire que le fichier XML
- mettre le fichier dans le répertoire de travail du programme
- remplacement de la référence dans le fichier xml par un chemin absolu
Qu'est-ce que je manque? Thx.
La solution
Si je comprends bien, si vous utilisez pyexpat directement, vous devez fournir votre propre ExternalEntityRefHandler
pour aller chercher la DTD externe et nourrissez à expat.
Voir, par exemple. xml.sax.expatreader
par exemple code (méthode external_entity_ref
, la ligne 374 dans le python 2.6).
Il serait sans doute préférable d'utiliser une interface de niveau supérieur, comme SAX (via expatreader
) si vous le pouvez.
Autres conseils
BTW, je peux me aider temporairement en copiant les parties pertinentes du .dtd dans le fichier XML lui-même, comme dans
<!DOCTYPE dblp [
<!ENTITY Agrave "À" >
]>
mais cela ne résout pas vraiment le problème d'une manière générale.