3 votes

Filtrage du vidage XML de Wikipedia : erreur sur certains accents

Je suis en train d'indexer les dumps de Wikipédia. Mon analyseur SAX crée des objets Article pour le XML avec seulement les champs qui m'intéressent, puis les envoie à mon ArticleSink, qui produit des Documents Lucene.

Je veux filtrer les pages spéciales/méta comme celles préfixées par Catégorie: ou Wikipedia:, donc j'ai créé un tableau de ces préfixes et je teste le titre de chaque page contre ce tableau dans mon ArticleSink, en utilisant article.getTitle.startsWith(prefix). En anglais, tout fonctionne bien, j'obtiens un index Lucene avec toutes les pages sauf celles correspondant aux préfixes.

En français, les préfixes sans accent fonctionnent aussi (c'est-à-dire filtrent les pages correspondantes), certains des préfixes accentués ne fonctionnent pas du tout (comme Catégorie:), et certains fonctionnent la plupart du temps mais échouent sur certaines pages (comme Wikipédia:) mais je ne peux pas voir de différence entre les lignes correspondantes (avec less).

Je ne peux pas vraiment inspecter toutes les différences dans le fichier en raison de sa taille (5 Go), mais il semble qu'il s'agisse d'un XML UTF-8 correct. Si je prends une portion du fichier avec grep ou head, les accents sont corrects (même sur les pages incriminées, le Catégorie:something est correctement affiché par grep). D'autre part, quand je recrée un XML wiki en coupant le fichier original avec tail/head, la même page (ici Catégorie:Rock par ville) est filtrée dans le petit fichier, pas dans l'original…

Des idées ?

Alternatives que j'ai essayées :

Obtenir le fichier (les lignes commentées ont été essayées sans succès*) :

FileInputStream fis = new FileInputStream(new File(xmlFileName));
//ReaderInputStream ris = ReaderInputStream.forceEncodingInputStream(fis, "UTF-8" );
//(fonction personnalisée ouvrant le flux, 
//le lisant en UTF-8 dans un Reader et renvoyant un autre flux de bits)
//InputSource is = new InputSource( fis ); is.setEncoding("UTF-8");
parser.parse(fis, handler);

Préfixes filtrés :

ignoredPrefix = new String[] {"Catégorie:", "Modèle:", "Wikipédia:",
    "Cat\uFFFDgorie:", "Mod\uFFFDle:", "Wikip\uFFFDdia:", //caractère non valide
    "Catégorie:", "Modèle:", "Wikipédia:", // UTF-8 comme ISO-8859-1
    "Image:", "Portail:", "Fichier:", "Aide:", "Projet:"}; // ceux-là fonctionnent toujours

* ERRATUM

En fait, c'est de ma faute, celle que j'ai essayée fonctionne, j'ai testé le mauvais index :

InputSource is = new InputSource( fis );
is.setEncoding("UTF-8"); // forcer l'interprétation en UTF-8
parser.parse(fis, handler);

2voto

Thomas Points 8142

Étant donné que vous écrivez les préfixes sous forme de chaînes de caractères simples dans votre fichier source, vous voulez vous assurer d'enregistrer ce fichier .java en UTF-8, également (ou tout autre encodage prenant en charge les caractères spéciaux que vous utilisez). Ensuite, cependant, vous devez indiquer au compilateur dans quel encodage se trouve le fichier avec le drapeau -encoding:

javac -encoding utf-8 *.java

Pour la source XML, vous pourriez essayer

Reader r = new InputStreamReader(new FileInputStream(xmlFileName), "UTF-8");

Les InputStreams ne traitent pas les encodages car ils sont basés sur les octets, et non sur les caractères. Ici, nous créons donc un Reader à partir d'un FileInputStream - ce dernier (flux) ne connaît pas les encodages, mais le premier (lecteur) oui, car nous donnons l'encodage dans le constructeur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X