Je suis analytique (beaucoup de) fichiers XML contenant des références d'entité que je ne sais pas à l'avance (ne peut pas changer ce fait).
Par exemple: P>
I'm content with very important stuff.
3 Réponses :
Étant donné que votre entrée XML semble être disponible sous forme de chaîne, pourriez-vous ne pas effectuer de pré-traitement simple avec un remplacement d'expression régulier?
xml = "..."; /* replace entities before parsing */ for (Map.Entry<String,String> entry : entityMapping.entrySet()) { xml = xml.replaceAll("&" + entry.getKey() + ";", entry.getValue()); } DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); ...
Je ne connais pas toutes les entités à l'avance (comme je l'ai déjà mentionnée dans ma question), je connais seulement un sous-ensemble. Et où est le point d'utiliser XML pour lequel des analyseurs déjà mûrs existent lorsque je finirai par écrire mon propre analyseur afin que je puisse travailler avec des données XML?
Le point concerne: ces analyseurs matures sont conçus pour gérer XML bien formé. Vous n'avez pas de XML bien formé et vous recherchez des solutions de contournement pour que les analyseurs soient manipulés de toute façon.
Eh bien, nous pouvons discuter beaucoup, j'ai toujours ce problème à résoudre.
@Chris: Je parlais de votre échantillon de code d'origine dans mon utilisation du hashmap "EntityMapping". Si vous ajoutez quelque chose comme xml = xml.replaceall ("& [^;] *;", ""); code> après la boucle, ma méthode vous permet de traiter des références d'entité inconnue. Vous avez raison que ce soit ennuyant d'utiliser de tels travaux, mais comme vous essayez d'atteindre quelque chose qu'un XML n'a pas été conçu pour traiter, un piratage comme celui ci-dessus pourrait bien être un moyen de résoudre ce problème. Et franchement, ce n'est pas une grande partie d'un "analyseur" que vous devez écrire, c'est plutôt un prétraiteur (très simple).
Vous pouvez ajouter les entités à la befinning du fichier. Regardez ici pour plus d'infos. P>
Vous pouvez également jeter un coup d'œil à Ce fil où quelqu'un semble ont mis en place une interface d'entitéresolver (vous pouvez également implémenter EntityResolver2!) Où vous pouvez traiter les entités à la volée (par exemple avec votre carte proposée). P>
AVERTISSEMENT: Il y a un bogue! dans JDK6, mais Vous pouvez l'essayer avec JDK5 P>
Il n'y a pas de fichier DTD qui définit comment traduire les références et je ne connais pas non plus toutes les références d'entité pouvant survenir dans le document afin que je ne puisse pas le créer moi-même. Je connais seulement un petit sous-ensemble des références qui se produisent fréquemment, mais je ne peux pas non plus dire comment "Big" Ce sous-ensemble est.
OK, mais vous transformez ces concédies aux sections CDATA brutes ou que vous pourriez «sauter» ou transformer ces entités à la volée en XML-PURE-Texte valide ou STH. comme ça. Sinon, vous n'aurez pas de chance.
L'API STAX a un soutien pour cela. Jetez un coup d'œil à xmlinputFactory , Il a un Propriété d'exécution A > qui dicte si des entités internes sont élargies ou non disponibles. Si défini sur Si vous voulez toujours un DOM comme résultat final, vous peut la chaîner ensemble comme ceci: p> Dans ce cas, le DOM résultant contiendra des nœuds de false code>, le flux d'événement STAX contiendra des instances de
entityreference code> pour représenter les entités non expansées.
org.w3c.dom.entityreference code> mélangé avec les nœuds de texte. Vous pouvez ensuite les traiter comme vous le voyez. P> p>
Je ne suis pas assez familier avec la boîte à outils SAX pour connaître son API, mais je peux imaginer qu'il a un
... résolveur code> associé à celui-ci. Cette classe serait responsable de la résolution de ces références. Que le modèle .NET fonctionne. Je pense que les concepts sont en grande partie la même chose.
Vous voulez dire comme l'entitéresolver? Cela semble certainement comme ça devrait fonctionner, mais quand je regarde son API, il ne semble pas sembler d'être dirigé vers ce genre d'entité. Cependant, essayant qu'il ne devrait faire aucun mal.
EntityResolver Code> est destiné à résoudre les entités externes i> (par exemple une DTD), mais nous recherchons quelque chose qui gère interne i> entités.
L'entitéresolver2 ne pourrait-elle pas faire ceci via une résolution d'entréeSource (chaîne Nom B>, chaîne Publier, base de base, String SystemID)?