2009-05-10 5 views
1

Ce code est en cours d'exécution sur Blackberry JDE v4.2.1 Il s'agit d'une méthode qui effectue des appels API Web renvoyant XML. Parfois, le XML retourné n'est pas bien formé et j'ai besoin de supprimer tous les caractères invalides avant d'analyser.Comment supprimer les caractères XML non valides d'un flux dans J2ME? org.xml.sax.SAXParseException: caractère non valide

Actuellement, j'obtiens: org.xml.sax.SAXParseException: Invalid character '' encountered. Je voudrais voir des idées d'un moyen rapide d'attacher un stripper de caractère invalide sur le flux d'entrée de sorte que le flux circule simplement à travers le validateur/décapant et dans l'appel d'analyse. c'est-à-dire que j'essaie d'éviter d'enregistrer le contenu du flux.

Code existant:

gestionnaire est une substitution de DefaultHandler
URL est une chaîne contenant l'API URL

hconn = (HttpConnection) Connector.open(url,Connector.READ_WRITE,true); 

... 

try{ 
    XMLParser parser = new XMLParser(); 
    InputStream input = hconn.openInputStream(); 
    parser.parse(input, handler); 
    input.close(); 
} catch (SAXException e) { 
    Logger.getInstance().error("getViaHTTP() - SAXException - "+e.toString()); 
} 

Répondre

2

Il est difficile d'attacher un strip-teaseur sur l'InputStream car les flux sont orientés sur les octets. Il pourrait être plus logique de le faire sur un Reader. Vous pourriez faire quelque chose comme un StripReader qui enveloppe un autre lecteur et traite des erreurs. Voici une preuve rapide, non testé, concept pour cela:

public class StripReader extends Reader 
{ 
    private Reader in; 
    public StripReader(Reader in) 
    { 
    this.in = in; 
    } 

    public boolean markSupported() 
    { 
    return false; 
    } 

    public void mark(int readLimit) 
    { 
    throw new UnsupportedOperationException("Mark not supported"); 
    } 

    public void reset() 
    { 
    throw new UnsupportedOperationException("Reset not supported"); 
    } 

    public int read() throws IOException 
    { 
    int next; 
    do 
    { 
     next = in.read(); 
    } while(!(next == -1 || Character.isValidCodePoint(next))); 

    return next; 
    } 

    public void close() throws IOException 
    { 
    in.close(); 
    } 

    public int read(char[] cbuf, int off, int len) throws IOException 
    { 
    int i, next = 0; 
    for(i = 0; i < len; i++) 
    { 
     next = read(); 
     if(next == -1) 
     break; 
     cbuf[off + i] = (char)next; 
    } 
    if(i == 0 && next == -1) 
     return -1; 
    else 
     return i; 
    } 

    public int read(char[] cbuf) throws IOException 
    { 
    return read(cbuf, 0, cbuf.length); 
    } 
} 

Vous pouvez ensuite construire un InputSource de lecteur puis ensuite faire l'analyse syntaxique en utilisant la InputSource.

+0

Depuis Blackberry n'a apparemment pas FilterReader non plus, j'ai modifié le ci-dessus pour ne pas l'utiliser. –

+0

RIM n'inclut pas non plus Character.isValidCodePoint() Je devais rouler le mien. Mais, cette méthode semble fonctionner - sur le simulateur au moins. Heureusement, il tiendra également et ne sera pas trop lent sur un appareil réel. Merci! –

+0

De rien. Assurez-vous de bien tester. Cela va inévitablement ralentir les choses puisque chaque personnage doit être (re) vérifié. Cependant, je ne pense pas que je fasse des copies inutiles. P.S. Je suis curieux de savoir comment vous avez implémenté isValidCodePoint. –

0

Utiliser un FilterInputStream. Remplacez FilterInputStream#read pour filtrer les octets incriminés.

+0

Le problème est que cela nécessite la duplication de la logique de décodage de caractères dans le flux. –

+1

Il ne peut pas être un moyen d'éviter cela sans personnaliser XMLParser? –

+0

RIM n'a pas FilterInputStream http://www.blackberry.com/developers/docs/4.2.1api/index.html –

Questions connexes