SAXParser Сбой для определенных данных
Я пытаюсь проанализировать файл XML, который выглядит следующим образом:
<?xml version="1.0" encoding="utf-8"?>
<downloaddata>
<downloaditem itemid="1">
<title>Abdul kalaam Inspirational Talk</title>
<downloadlink>http://o-o.preferred.spectranet-blr1.v8.lscache4.c.youtube.com/videoplayback?upn=Rxb-DvFeBTE&sparams=cp%2Cid%2Cip%2Cipbits%2Citag%2Cratebypass%2Csource%2Cupn%2Cexpire&fexp=906512%2C907217%2C907335%2C921602%2C919306%2C919316%2C904455%2C919324%2C904452&itag=18&ip=203.0.0.0&signature=96D7FA17DF684B4C2CD30F12251F3263C83EC443.05F62E98E1059BB44459ABF319F50DC4B7E6D90E&sver=3&ratebypass=yes&source=youtube&expire=1337691481&key=yt1&ipbits=8&cp=U0hSTFZUT19NS0NOMl9OTlNFOmlwaTFSSGFfd3NK&id=67ffa1d50864f57d&title=Abdul%20Kalam%20inspirational%20Speech%20on%20Leadership%20and%20Motivation</downloadlink>
</downloaditem>
</downloaddata>
Кажется, что синтаксический анализ не удается, когда данные для downloadlink
тег как указано выше. Я попытался заменить данные чем-то еще такой же длины, и это работает.
Ниже приведен код Android, который я использую.
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import android.os.Environment;
public class Wilxmlparser extends DefaultHandler{
List<VideoDetails> downloadList;
private String tempVal;
private VideoDetails tempVidDet;
public Wilxmlparser(){
}
public void parseXML() {
//get a factory
SAXParserFactory spf = SAXParserFactory.newInstance();
try {
//get a new instance of parser
SAXParser sp = spf.newSAXParser();
File downloadInfo =new File(Environment.getExternalStorageDirectory()+"/watchitlater/config/downloadinfo1.xml");
//parse the file and also register this class for call backs
sp.parse(downloadInfo, this);
}catch(SAXException se) {
se.printStackTrace();
}catch(ParserConfigurationException pce) {
pce.printStackTrace();
}catch (IOException ie) {
ie.printStackTrace();
}
}
//Event Handlers
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
//reset
tempVal = "";
if(qName.equalsIgnoreCase("downloaditem")) {
tempVidDet = new VideoDetails();
tempVidDet.setItemId(Integer.parseInt(attributes.getValue("itemid")));
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
tempVal = new String(ch,start,length);
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if(qName.equalsIgnoreCase("downloaditem")) {
downloadList.add(tempVidDet);
}else if (qName.equalsIgnoreCase("title")) {
tempVidDet.setTitle(tempVal);
}else if (qName.equalsIgnoreCase("downloadlink")) {
tempVidDet.setDownloadLink(tempVal);
}
}
}
Приведенный выше код не дает обратный вызов endElement
для вышеуказанного XML-файла. Однако, если XML должен быть как
<?xml version="1.0" encoding="utf-8"?>
<downloaddata>
<downloaditem itemid="1">
<title>Abdul kalaam Inspirational Talk</title>
<downloadlink>http://www.gmail.com/hello/world/sdfsdf%20.@@%!@# ($dwe</downloadlink>
</downloaditem>
</downloaddata>
или же
<?xml version="1.0" encoding="utf-8"?>
<downloaddata>
<downloaditem itemid="1">
<title>Abdul kalaam Inspirational Talk</title>
<downloadlink>httphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttpa</downloadlink>
</downloaditem>
</downloaddata>
Тогда все работает нормально. Что я делаю неправильно?
2 ответа
Причина, по которой ваш синтаксический анализатор не может проанализировать рассматриваемый xml, заключается в том, что это недопустимый xml. Раздел данных, который вызывает вашу проблему, содержит символы, которые должны быть экранированы. См. Символы и экранирование в статье в Википедии о XML для получения дополнительной информации.
Это лучше всего исправить во всех случаях, когда производится XML, и самое простое решение - обернуть оскорбительный текст в раздел CDATA.
Как только данные исправлены, вы также можете увидеть проблему, вызванную неправильным представлением в вашем коде анализа.
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
tempVal = new String(ch,start,length);
}
не всегда будет получать все символы между начальным и конечным тегами, поскольку контракт для этого метода позволяет вызывать его более одного раза. Вместо простого копирования в строку, вам нужно добавить в строковый буфер, который инициализируется в startElement
метод и используется в endElement
метод.
Смотрите мой ответ на еще один вопрос SO, чтобы узнать больше об этом characters
вопрос разбора метода.
Парсер не будет разбирать специальные символы. Вы должны заменить, если все специальные символы присутствуют в
Blockquote
Blockquote
Вы можете передать этот текст в TextUtils.htmlEncode(строка), а затем начать анализ. Я думаю, что это будет работать или изменить его на стороне сервера, чтобы дать вам данные, закодированные с помощью кодировки UTF-8, а на стороне устройства вы можете декодировать с помощью той же самой кодировки