Ver la Versión Completa : [ CONSULTA ] Detectar saltos de linea en JSoup
kaiser75
09/07/18, 10:39:14
Estoy parseando datos de un rss con jsoup que muestro en un activity, funciona bien, lo que pasa es que los párrafos me los muestra juntos, no separados por un salto de linea y un espacio, si no como un bloque entero de texto, sabéis como detectar en un String el punto y el espacio o salto de linea y añadir una linea vacia para separar el texto? Con "replace(...etc)" quizas?
mocelet
09/07/18, 11:06:36
Preguntas:
- ¿Puedes poner un ejemplo del código HTML del RSS? ¿Y cómo es la String resultante?
- ¿Qué es lo que extrae JSoup, el HTML o texto sin formato?
- ¿Dónde lo muestras? ¿En un TextView, en un WebView?
Con String replaceAll claro que puedes reemplazar cosas con expresiones regulares, pero si los saltos de línea los ha fusilado JSoup habrá que configurar JSoup en vez de "adivinar" dónde están los saltos.
Si quieres texto simple sin formato con saltos de línea lo más seguro es que tengas que configurar el parseo de JSoup como indican en este tutorial https://www.javacodeexamples.com/jsoup-preserve-new-lines-example/799 , es decir, añadir después de los br y p una nueva línea y luego ya limpiar el html de etiquetas pero conservando los saltos de línea. Eso suponiendo que quieras texto simple respetando los saltos.
Sin embargo, otra opción es conservar los p y los br y mostrar HTML en los TextView o WebView o lo que uses. Con JSoup podrías eliminar los enlaces o etiquetas de formato que no quieras (para eso está la whitelist del método clean). Pero igual te interesa conservar las negritas, cursivas, etc. Eso ya depende de lo que estés haciendo y si te importa el formato o no.
kaiser75
09/07/18, 20:29:10
Preguntas:
- ¿Puedes poner un ejemplo del código HTML del RSS? ¿Y cómo es la String resultante?
- ¿Qué es lo que extrae JSoup, el HTML o texto sin formato?
- ¿Dónde lo muestras? ¿En un TextView, en un WebView?
1- es un Rss de noticias de internet, els String es texto
2- Estrae las etiquetas <title>,<description>...etc
3- en un TextView, uno para el titulo y otro para la descripcion.
La descripcion me muestra el texto sin las etiquetas <![CDATA], o sea, solo el texto simple a secas, muestra los saltos de linea pero muy juntos, quiero meter una linea en blanco.
mocelet
09/07/18, 20:43:12
Vale, ¿y cómo es una String de la descripción con saltos de línea? En otras palabras, ¿el salto de línea cómo aparece en la String? ¿En HTML con un <br/>, como un carácter de nueva línea \n?
Cuando dices que te muestra los saltos de línea pero muy juntos, ¿qué quieres decir? ¿Que entonces sí que te muestra los saltos de línea? (antes decías que el problema era que te salía el texto seguido)
Por eso te pedía un ejemplo de qué String tienes, qué ves ahora y qué esperas ver XD
kaiser75
10/07/18, 10:06:01
No tiene <br/>, cada parrafo esta con etiquetas <p></p>, un ejemplo:
Como se ve ahora:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse
congue aliquet lorem, non accumsan est aliquam sed. Vivamus et turpis
viverra, porta velit eget, euismod urna. Ut varius a est at condimentum.
Sed pulvinar sed tellus vel facilisis. <--- fin </p>, SALTO DE LINEA y texto seguido
Proin ut condimentum mi, eget consectetur
nisi. Proin pulvinar, sem sit amet dictum pharetra, nisl purus aliquam purus, a
hendrerit massa odio a ligula. Suspendisse ac tortor lacinia lacus suscipit semper.
Como deberia verse:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse
congue aliquet lorem, non accumsan est aliquam sed. Vivamus et turpis
viverra, porta velit eget, euismod urna. Ut varius a est at condimentum.
Sed pulvinar sed tellus vel facilisis. <--- SALTO DE LINEA + ESPACIO
Proin ut condimentum mi, eget consectetur
nisi. Proin pulvinar, sem sit amet dictum pharetra, nisl purus aliquam purus, a
hendrerit massa odio a ligula. Suspendisse ac tortor lacinia lacus suscipit semper.
el texto se muestra correctamente, es mas cuestion de estetica para no ver todo el articulo como un solo parrafo.
mocelet
10/07/18, 11:13:44
OK, entonces la String que pones en el TextView no es texto sino HTML con sus etiquetas. Imagino entonces que tienes algo tal que así y llamas al fromHtml porque, si no, verías las etiquetas en el text view:
textView.setText(Html.fromHtml("<p>L1</p><p>L2</p>"));
Android por defecto mete dos retornos de carro entre bloques, es decir, una línea en blanco. De hecho ese ejemplo deja bastante separación entre L1 y L2. Si por casualidad llamas al fromHtml con algún atributo como el modo compacto entonces es normal que entre los párrafos no haya una línea en blanco. Sin atributo usa el modo legacy por defecto que mete una línea en blanco.
EDIT: Si el String que te da JSoup NO tiene las etiquetas <p> porque ya ha limpiado el HTML y ha metido un retorno de carro nada más, entonces tienes que hacer lo del tutorial que te decía en mi primera respuesta, que es meter a mano un retorno de carro extra después de los </p>.
kaiser75
10/07/18, 12:52:03
Exacto, limpio el html porque si no me muestra toda la perefernalia de etiquetas mezcladas con el texto, con esta clase.
String removeCdata(String data) {
data = data.replace("<![CDATA[", "");
data = data.replace("]]>", "");
return data;
}
y despues lo muestro...
String descripcion = removeCdata(item.select("content|encoded").text());
La fuente del RSS se muestra asi...
<content:encoded><![CDATA[<p>Aqui el texto o parrafo...etc</p>
<p>Aqui otro parrafo, bla bla</p>
<p>y asi unos cuantos parrafos...etc</p>]]></content:encoded>
mocelet
10/07/18, 13:05:58
Entiendo, la opción chapucilla es hacer un replace de /n por /n/n o seguir el tutorial que enlacé para añadir un /n extra.
Pero yo creo que es mejor que al TextView le pases HTML con la función fromHtml como en el ejemplo que te ponía. Aprovechando eso sí que JSoup tiene un método clean y su whitelist para dejar el HTML solo con las etiquetas que te importan (p, br, alguna etiqueta de formato si quieres negritas y cursivas y poco más).
kaiser75
10/07/18, 13:35:02
Gracias mocelet, mirare el tutorial que pusiste asi como los metodos de JSoup a ver que tal...:ok:
mocelet
10/07/18, 14:06:29
Gracias mocelet, mirare el tutorial que pusiste asi como los metodos de JSoup a ver que tal...:ok:
El tutorial ese olvídalo, era para conservar retornos de carro, pero es mejor usar directamente HTML en el TextView para lo que quieres.
He cogido tu ejemplo para hacer una prueba. Aunque está en Kotlin no te costará nada escribirlo en Java
val rssText = "<content:encoded><![CDATA[<p>Aqui el <b>texto</b> o parrafo...etc</p><p>Aqui otro parrafo, bla bla</p><p>y asi unos cuantos parrafos...etc</p>]]></content:encoded>"
val item = Jsoup.parse(rssText)
val rawDescriptionHtml = removeCdata(item.select("content|encoded").html())
val whitelist = Whitelist.simpleText().addTags("p", "br")
val cleanDescriptionHtml = Jsoup.clean(rawDescriptionHtml, whitelist)
textView.setText(Html.fromHtml(cleanDescriptionHtm l))
El item es el mismo que ya tienes. rawDescriptionHtml es un String con la descripción tal cual sin el CDATA, pero en vez de text() como html() para que te conserve las etiquetas. Como el RSS puede tener cosas raras lo limpiamos con el método clean de Jsoup pasándole una whitelist.
Hay varios tipos de whitelist, si el formato negrita, cursiva, etc. tampoco lo quieres en vez de simpleText() usa none(). El addTags es necesario para especificar qué etiquetas quieres que te conserve, en este caso p y br que son las únicas que marcan párrafos.
Con el html limpito lo presentamos en el textView y ya está, no hay que añadir retornos de carro ni hacer chapucillas.
kaiser75
10/07/18, 19:23:21
Genial... :aplausos:, eso es exactamente lo que buscaba
kaiser75
11/07/18, 12:01:16
Y ya para aprovechar el post, como puedo formatear la fecha obtenida de las etiquetas "<pubDate>"?.
asi la obtengo:
String fecha = item.select("pubDate").text();
la fecha se muestra asi "Wed, 11 Jul 2018 12:15:23 +0200" y queria formatearla a algo mas simple como "Mie 11 Julio 12:15" por ejemplo.
--- Nada, ya lo he solucionado
mocelet
11/07/18, 13:30:58
El formato de pubDate está especificado en la RFC-822, en la mayoría de los casos te valdrá un SimpleDateFormat con el patrón adecuado para convertirlo a Date. Una vez tengas el Date, con otro formateador obtienes el resultado final que quieras presentar.
Algo así, no estoy tratando los errores ni contemplando casos poco habituales pero posibles como que no salga el día o no salgan los segundos:
val pubDateRfc822 = "Wed, 11 Jul 2018 12:15:23 +0200"
val rfc822Format = SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.US);
val pubDate = rfc822Format.parse(pubDateRfc822)
val targetFormat = SimpleDateFormat("EEE d MMMM HH:mm") // mié. 11 julio 12:15
val result = targetFormat.format(pubDate)
El primer SimpleDateFormat tiene el patrón de pubDate, el Locale es US porque el nombre del día está en inglés. De hecho el día es opcional, si quieres un código más robusto además de tratar las excepciones que lanza el método parse() deberías contemplar el caso de que no haya día con otro patrón (que sería igual sin el "EEE, " del principio). De hecho... los segundos también son opcionales, así que las opciones se multiplican: "EEE, dd MMM yy HH:mm:ss z", "EEE, dd MMM yy HH:mm z", "dd MMM yy HH:mm:ss z" y "dd MMM yy HH:mm z".
El segundo SimpleDateFormat es ya para formatear la fecha como te apetezca, ahí te he puesto el del ejemplo que querías pero puedes jugar con los patrones que vienen explicados en la documentación de SimpleDateFormat (https://developer.android.com/reference/java/text/SimpleDateFormat). Al no poner Locale lo hará en el idioma del dispositivo.
EDIT: No había leído lo de que ya estaba solucionado, imagino que has usado el SimpleDateFormat igualmente. Ten en cuenta que hay formas de parsear la fecha que pierden la información de la zona horaria y entonces no va a poner la fecha bien. Lo ideal sería usar una biblioteca o una función que esté probada con todos los casos y sea robusta. Tampoco hace falta reinventar la rueda.
vBulletin® v3.8.1, Copyright ©2000-2026, Jelsoft Enterprises Ltd.