Как мне удалить недопустимые символы XML из потока в J2ME? org.xml.sax.SAXParseException: недопустимый символ

Этот код работает на Blackberry JDE v4.2.1. Он находится в методе, который выполняет вызовы веб-API, возвращающие XML. Иногда возвращаемый XML имеет неправильный формат, и мне нужно удалить все недопустимые символы перед синтаксическим анализом.

В настоящее время я получаю: org.xml.sax.SAXParseException: Invalid character '' encountered.

Я хотел бы увидеть идеи быстрого способа прикрепления недопустимого средства удаления символов во входном потоке, чтобы поток просто проходил через средство проверки / удаления и в вызов синтаксического анализа. т.е. я пытаюсь избежать сохранения содержимого потока.

Существующий код:

обработчик - это переопределение DefaultHandler
url - это строка, содержащая 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());
}

person JR Lawhorne    schedule 10.05.2009    source источник


Ответы (2)


Трудно прикрепить стриппер к InputStream, потому что потоки ориентированы на байты. Возможно, имеет смысл сделать это в Reader < / а>. Вы могли бы сделать что-то вроде StripReader, который обертывает другой ридер и обрабатывает ошибки. Ниже приведено быстрое, непроверенное доказательство концепции этого:

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);
    }
}

Затем вы должны создать InputSource. затем Reader выполните синтаксический анализ, используя InputSource.

person Matthew Flaschen    schedule 10.05.2009
comment
Поскольку у Blackberry, по-видимому, тоже нет FilterReader, я изменил приведенное выше, чтобы не использовать его. - person Matthew Flaschen; 10.05.2009
comment
RIM также не включает Character.isValidCodePoint (), который мне пришлось накатить самостоятельно. Но, похоже, этот метод работает - по крайней мере, на симуляторе. Надеюсь, он также будет работать и не будет слишком медленным на реальном устройстве. Спасибо! - person JR Lawhorne; 10.05.2009
comment
Пожалуйста. Только обязательно хорошо протестируйте. Это неизбежно замедлит процесс, поскольку каждый символ должен быть (повторно) проверен. Однако я не думаю, что делаю ненужное копирование. P.S. Мне любопытно, как вы реализовали isValidCodePoint. - person Matthew Flaschen; 10.05.2009
comment
Это не будет хорошо отображаться в этом блоке комментариев, но вот метод, который я использую для проверки символа XML: private boolean isValidXMLChar (int ch) {if ((ch == 0x9) || (ch == 0xA) || (ch == 0xD) || ((ch ›= 0x20) && (ch‹ = 0xD7FF)) || ((ch ›= 0xE000) && (ch‹ = 0xFFFD)) || ((ch ›= 0x10000) && (ch ‹= 0x10FFFF))) вернуть истину; иначе вернет ложь; } - person JR Lawhorne; 18.05.2009

Используйте FilterInputStream. Переопределить FilterInputStream # read для фильтрации ошибочных байтов.

person alphazero    schedule 10.05.2009
comment
Проблема в том, что требуется дублировать логику декодирования символов в потоке. - person Matthew Flaschen; 10.05.2009
comment
Может быть, нет способа избежать этого без настройки XMLParser? - person JR Lawhorne; 10.05.2009
comment
RIM не имеет FilterInputStream blackberry.com/developers/docs/4.2. 1api / index.html - person JR Lawhorne; 10.05.2009
comment
Почему бы просто не использовать настроенный XMLParser только при наличии исключения SAXException? Казалось бы, если вы получите плохой XML-файл, лучше всего будет отклонить весь файл, так как поврежденная часть может привести к извлечению плохих данных. - person James Black; 10.05.2009