SAXParser fallando para un dato específico

Estoy tratando de analizar un archivo XML que se ve así:

<?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>

Parece que el análisis está fallando cuando los datos para el downloadlink la etiqueta es como arriba. He intentado reemplazar los datos con algo más de la misma longitud y funciona.

A continuación se muestra el código de Android que estoy usando.

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

El código anterior no da una devolución de llamada a endElement para el archivo xml anterior. sin embargo, si el xml fuera como

<?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>

or

<?xml version="1.0" encoding="utf-8"?>
<downloaddata>
    <downloaditem itemid="1">
        <title>Abdul kalaam Inspirational Talk</title>
            <downloadlink>httphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttphttpa</downloadlink>
    </downloaditem>
</downloaddata>

Entonces funciona bien. ¿Qué estoy haciendo mal?

preguntado el 22 de mayo de 12 a las 12:05

2 Respuestas

Parser no analizará caracteres especiales. Debe reemplazar si todos los caracteres especiales presentes en el

Blockquote

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

Blockquote

puede pasar este texto a TextUtils.htmlEncode (cadena) y luego comenzar a analizar. Creo que funcionará o lo cambiará del lado del servidor para brindarle datos codificados con el juego de caracteres UTF-8 y en el lado del dispositivo puede decodificar con el mismo juego de caracteres

contestado el 22 de mayo de 12 a las 12:05

Gracias por su respuesta. ¿Puede explicarme cómo puedo lograrlo, sin romper la URL? Cualquier ejemplo de código será muy apreciado. Gracias. - PavanMysore

¿Ha intentado pasar toda la respuesta a TextUtils.htmlEncode(string); y luego comenzar a analizar - bhavindesai

Solo intente: configure su InputSource manualmente en ISO como inputSource.setEncoding("UTF-8") o inputSource.setEncoding("ISO-8859-1") y luego páselo al análisis del analizador SAX() - bhavindesai

el analizador tiene problemas para analizar el carácter '&' - bhavindesai

¡Gracias! Intentaré volver en un rato. - PavanMysore

La razón por la que su analizador no puede analizar el xml en cuestión es que no es un xml válido. La sección de datos que está causando su problema tiene caracteres que se deben escapar. Ver Personajes y escape en el artículo de wikipedia sobre XML para obtener más información.

Esto se corrige mejor en lo que sea que esté produciendo el xml, y la solución más fácil sería envolver el texto ofensivo en un Sección CDATA.

Sin embargo, una vez que se corrigen los datos, también puede ver un problema causado por un concepto erróneo en su código de análisis.

@Override
public void characters(char[] ch, int start, int length) throws SAXException {
   tempVal = new String(ch,start,length);
}

no siempre obtendrá todos los caracteres entre las etiquetas de inicio y finalización, ya que el contrato de este método permite llamarlo más de una vez. En lugar de simplemente copiar en una cadena, debe agregar un búfer de cadena que se inicializa en el startElement método y utilizado en el endElement método.

Vea mi respuesta a otra pregunta SO un poco más sobre esto characters Problema de análisis del método.

contestado el 23 de mayo de 17 a las 11:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.