7 votes

Pourquoi org.apache.xerces.parsers.SAXParser ne saute-t-il pas le BOM dans un fichier XML encodé en utf8?

J'ai un xml avec un encodage utf8. Et ce fichier contient BOM au début du fichier. Donc, pendant l'analyse, je suis confronté à org.xml.sax.SAXParseException : Le contenu n'est pas autorisé dans le prologue. Je ne peux pas supprimer ces 3 octets des fichiers. Je ne peux pas charger le fichier en mémoire et les supprimer ici (les fichiers sont volumineux). Donc, pour des raisons de performances, j'utilise un analyseur SAX et je veux juste sauter ces 3 octets s'ils sont présents avant la balise "". Devrais-je hériter de InputStreamReader pour cela?

Je suis nouveau en java - montrez-moi le bon chemin s'il vous plaît.

4voto

Adrian Cox Points 3214

Cela s'est déjà produit auparavant, et j'ai trouvé la réponse sur Stack Overflow lorsque cela m'est arrivé. La réponse liée utilise un PushbackInputStream pour tester le BOM.

3voto

javanna Points 24751

J'ai rencontré le même problème et je l'ai résolu avec ce code :

private static InputStream checkForUtf8BOM(InputStream inputStream) throws IOException {
    PushbackInputStream pushbackInputStream = new PushbackInputStream(new BufferedInputStream(inputStream), 3);
    byte[] bom = new byte[3];
    if (pushbackInputStream.read(bom) != -1) {
        if (!(bom[0] == (byte) 0xEF && bom[1] == (byte) 0xBB && bom[2] == (byte) 0xBF)) {
            pushbackInputStream.unread(bom);
        }
    }
    return pushbackInputStream;
}

2voto

tuku Points 126
private static char[] UTF32BE = { 0x0000, 0xFEFF };
private static char[] UTF32LE = { 0xFFFE, 0x0000 };
private static char[] UTF16BE = { 0xFEFF };
private static char[] UTF16LE = { 0xFFFE };
private static char[] UTF8 = { 0xEFBB, 0xBF };

private static boolean removeBOM(Reader reader, char[] bom) throws Exception {
    int bomLength = bom.length;
    reader.mark(bomLength);
    char[] possibleBOM = new char[bomLength];
    reader.read(possibleBOM);
    for (int x = 0; x < bomLength; x++) {
        if ((int) bom[x] != (int) possibleBOM[x]) {
            reader.reset();
            return false;
        }
    }
    return true;
}

private static void removeBOM(Reader reader) throws Exception {
    if (removeBOM(reader, UTF32BE)) {
        return;
    }
    if (removeBOM(reader, UTF32LE)) {
        return;
    }
    if (removeBOM(reader, UTF16BE)) {
        return;
    }
    if (removeBOM(reader, UTF16LE)) {
        return;
    }
    if (removeBOM(reader, UTF8)) {
        return;
    }
}

utilisation:

// xml peut être lu à partir d'un fichier, URL ou d'une chaîne via un flux
URL url = new URL("some xml url");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(url.openStream()));
removeBOM(bufferedReader);

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