SAX обрабатывает специальные символы - PullRequest
0 голосов
/ 13 сентября 2011

Я пытаюсь проанализировать XML-файл с Java и SAX для устройства Android. Я получил из интернета и при разборе я получаю ExpatException: не правильно сформирован (неверный токен) на символ "é". Есть ли способ обработки этих символов без необходимости изменения всех специальных символов в файле XML?

изменить: Вот часть моего кода, записывающая файл на мою SD-карту.

File SDCardRoot = Environment.getExternalStorageDirectory();
            File f = new File(SDCardRoot,"edt.xml");
            f.createNewFile();
            FileOutputStream fileOutput = new FileOutputStream(f);
            InputStream inputStream = urlConnection.getInputStream();


            byte[] buffer = new byte[1024];
            int bufferLength = 0;
            while ( (bufferLength = inputStream.read(buffer)) > 0 ) {
                fileOutput.write(buffer, 0, bufferLength);
            }

            fileOutput.close();

Вот часть моего xml:

<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet type="text/xsl" href="ttss.xsl"?>

<timetable>
<option combined="0" totalweeks="0" showemptydays="0" dayclass="reverse">
<link href="g56065.xml" class="xml">Imprimer</link>
<link href="g56065.pdf" class="pdf">Version PDF</link>
<weeks>Semaines</weeks>
<dates>Dates</dates>
<week>Semaine</week>
<date>Date</date>
<all>Toutes les semaines</all>
<notes>Remarques</notes>
<id>ID</id>
<tag>Champs Libre</tag>
<footer>Publié le 10/09/2011 22:14:28</footer>
... </timetable>

вот код разбора:

public class ParserSemaines extends DefaultHandler {
    private final String SEMAINE = "span";
    private final String DESCRIPTION = "description";
    private ArrayList<Semaine> semaines;
    private boolean inSemaine;
    private Semaine currentSemaine;
    private StringBuffer buffer;
    @Override
    public void processingInstruction(String target, String data) throws SAXException {
        super.processingInstruction(target, data);
    }
    public ParserSemaines() {
        super();
    }

    @Override
    public void startDocument() throws SAXException {
        super.startDocument();
        semaines = new ArrayList<Semaine>();
    }

    @Override
    public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
        buffer = new StringBuffer();
        if (localName.equalsIgnoreCase(SEMAINE)){
            this.currentSemaine = new Semaine();
            this.currentSemaine.setDate(attributes.getValue("date"));
            this.inSemaine = true;
        }
        if(localName.equalsIgnoreCase(DESCRIPTION)){
            this.currentSemaine.setDescription(buffer.toString());
        }
    }

    @Override
    public void endElement(String uri, String localName, String name) throws SAXException {
        if (localName.equalsIgnoreCase(SEMAINE)){
            this.semaines.add(currentSemaine);
            this.inSemaine = false;
        }
    }

    public void characters(char[] ch,int start, int length) throws SAXException{
        String lecture = new String(ch,start,length);
        if(buffer != null) buffer.append(lecture);
    }

    public ArrayList<Semaine> getData(){
        return semaines;
    }
}

вот код, который я использую для вызова синтаксического анализатора:

SAXParserFactory fabrique = SAXParserFactory.newInstance();
        SAXParser parseur = null;
        ArrayList<Semaine> semaines = null;
        try {
            parseur = fabrique.newSAXParser();
            DefaultHandler handler = new ParserSemaines();
            File f = new File(Environment.getExternalStorageDirectory(),"edt.xml");
            parseur.parse(f, handler);  
            semaines = ((ParserSemaines) handler).getData();
        }

Спросите, требуются ли какие-либо другие части кода.

После проверки выясняется, что в xml-файле на SD-карте отображается «é» как «½». Это должно быть проблемой, но я понятия не имею, почему. Я также пытался проанализировать URI, но это ничего не меняет, я всегда получаю одно и то же исключение.

Ответы [ 3 ]

1 голос
/ 14 сентября 2011

После проверки выясняется, что xml-файл на SD-карте показывает «é» как «ï "½».

Это указывает на проблему с кодировкой.

Код, который вы опубликовали, представляется правильной побайтной копией URL-адреса файла, поэтому файл должен точно соответствовать тому, что вы получаете с URL-адреса.Это означает, что ответ от сервера может не соответствовать ISO-8859-1.

Следующим моим шагом будет использование инструмента, такого как Fiddler , для проверки всего ответа, выплачивая определенныевнимание на:

  • Заголовок Content-Type.Если он сообщает вам другой набор символов, вам придется передать эту информацию в анализатор и / или вручную преобразовать ее.
  • Фактические возвращенные байты.Насколько вы знаете, и Content-Type и пролог XML могли бы лгать.Если файл действительно ISO-8859-1, то значение ударения e должно иметь значение байта 0xE9.Если содержимое действительно UTF-8, должна быть двухбайтовая последовательность 0xC3 0xA9 (см. здесь ).Вы показываете трехбайтовую последовательность, которая не имеет смысла.Но лучше проверить источник.

Кроме того, убедитесь, что вы не преобразуете файл в строку перед передачей его в SAX-анализатор.


Для справки: я написал минимальную программу, которая соединяется с URL-адресом OP и передает это соединение напрямую минимальному парсеру SAX.Оказалось, запустить без ошибок.Я также использовал анализатор DOM и убедился, что по крайней мере корневой элемент был проанализирован правильно.

public static void main(String[] argv)
throws Exception
{
   URL url = new URL("http://www.disvu.u-bordeaux1.fr/et/edt_etudiants2/Master/Semestre1/g56065.xml");
   InputStream in = url.openConnection().getInputStream();

   SAXParserFactory spf = SAXParserFactory.newInstance();
   SAXParser parser = spf.newSAXParser();
   parser.parse(in, new DefaultHandler());
   System.out.println("parse successful");
}
1 голос
/ 15 сентября 2011

Я наконец-то нашел решение. Вместо SAXparder я использую

android.util.Xml.parse(InputStream,Xml.Encoding.ISO_8859_1, DefaultHandler);

Спасибо всем за помощь, оказанную мне.

0 голосов
/ 13 сентября 2011

Может быть проблема с кодировкой. Попробуйте изменить его на ISO-8859-1.

В вашем xml попробуйте:

<?xml version="1.0" encoding="ISO-8859-1"?>

или, в своем коде, используйте:

inputSource.setEncoding("ISO-8859-1");
...