En este video te explicamos en detalle todo el proceso para publicar una Aplicación Android…
Proyecto tratamiento XML en Android utilizando DOM (II)
5.
Proyecto tratamiento XML en Android utilizando DOM (II)
Continuamos con el proyecto de tratamiento de ficheros XML en Android usando el modelo DOM, al que denominamos «ParsearXML», completando con esta segunda parte. las clases y ficheros de layout que lo componen.
Puedes descargar el código completo de esta Aplicación al final de este tutorial.
Documentación código fuente
ParsearXML\app\src\main\java\com\academiaandroid\parsearxml\TareaAsincronaListado.java
Esta clase que hereda de la clase AsyncTask
,se encargará de cargar en segundo plano toda la información del documento XML en memoria, para posteriormente mostrarla por pantalla:
1 2 |
class TareaAsincronaListado extends AsyncTask<String,String,List> { |
La clase AsyncTask
sobrescribe un método que devolverá un ArrayList
de objetos Cliente, para posteriormente visualizarlos en un control ListView
:
1 2 3 4 5 6 7 8 9 10 11 |
@Override protected List<Cliente> doInBackground(String... params) { registrosCliente = new ArrayList<>(); parser = new ParsearDOM(context); try { stream = context.openFileInput(params[0]); doc = parser.getDocument(stream); |
Se obtiene una colección de nodos Cliente:
1 2 |
NodeList nodeList = doc.getElementsByTagName(NODE_CLIENTE); |
Se inicializa un ArrayList que almacenará objetos de tipo Cliente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
arrayClientes = new ArrayList<>(); Cliente cliente; for (int i = 0; i < nodeList.getLength(); i++) { Element e = (Element) nodeList.item(i); cliente = new Cliente(parser.getValue(e,NODE_NOMBRE), parser.getValue(e,NODE_APELLIDO), parser.getValue(e,NODE_CUENTA), parser.getValue(e,NODE_TELEFONO)); arrayClientes.add(cliente); } } catch (FileNotFoundException ex) { ex.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return arrayClientes; } |
ParsearXML\app\src\main\java\com\academiaandroid\parsearxml\ParsearDOM.java
Clase que permite cargar,recorrer y leer el documento XML, para posteriormente tener acceso a la totalidad de la información:
1 2 |
public class ParsearDOM { |
A continuación, se implementa un método que devolverá la referencia al documento XML cargado en memoria:
1 2 3 |
public Document getDocument(InputStream inputStream) { |
Se asigna a una variable de tipo DocumentBuilderFactory
, una nueva instancia para definir una factoría, que permita a la aplicación producir un árbol de objetos DOM a partir del documento XML procesado:
1 2 3 4 |
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); try { |
Se obtiene la instancia del documento DOM del fichero XML:
1 2 |
DocumentBuilder db = factory.newDocumentBuilder(); |
Se instancia la clase InputSource
, para definir un recurso de entrada para la entidad XML:
1 2 |
InputSource inputSource = new InputSource(inputStream); |
Por último a la instancia Document
se le asigna el contenido del recurso de entrada del documento XML, devolviendo un nuevo objeto Document
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
document = db.parse(inputSource); } catch (ParserConfigurationException e) { Log.e("Error", e.getMessage()); return null; } catch (SAXException e) { Log.e("Error", e.getMessage()); return null; } catch (IOException e) { Log.e("Error", e.getMessage()); return null; } return document; } |
Otro de los método definidos será getValue()
, que mostrará el texto de cada nodo hijo (nodos finales):
1 2 3 4 5 6 |
public String getValue(Element item, String name) { NodeList nodes = item.getElementsByTagName(name); return this.getTextNodeValue(nodes.item(0)); } |
Por último, se construye u método que devolverá un String
con el texto de cada nodo hijo:
1 2 3 4 |
private final String getTextNodeValue(Node node) { Node child; |
Se comprueba que no sea nulo la referencia Node recibida:
1 2 3 |
if (node != null) { |
Se comprueba si el nodo actual tiene nodos hijos:
1 2 3 |
if (node.hasChildNodes()) { |
Se posiciona en el primer nodo hijo:
1 2 |
child = node.getFirstChild(); |
Se define un bucle while()
que comprueba en cada iteración si existe un próximo nodo hijo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
while(child != null) { if (child.getNodeType() == Node.TEXT_NODE) { return child.getNodeValue(); } child = child.getNextSibling(); } } } return ""; } } |
ParsearXML\app\src\main\res\layout\activity_main.xml
A nivel de layout, tendríamos activity_main.xml
, que define la interfaz de usuario para la creación de un documento XML. Este layout estará formado, entre otros, de cuatro controles EditText
(recogerá los datos de la ficha del cliente) y tres Button
(para los eventos de omitir, eliminar a crear un documento XML):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout<em>width="match</em>parent" android:layout<em>height="match<em>parent" android:paddingLeft="@dimen/activity</em>horizontal</em>margin" android:paddingRight="@dimen/activity<em>horizontal</em>margin" android:paddingTop="@dimen/activity<em>vertical<em>margin" android:paddingBottom="@dimen/activity</em>vertical</em>margin" tools:context="com.academiaandroid.parsearxml.TareasXML" android:orientation="horizontal"> <TableLayout android:layout_width="match_parent" android:layout_height="match_parent"> [...] <TableRow android:layout_width="match_parent" android:layout_height="match_parent"> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:inputType="textPersonName" android:ems="10" android:id="@+id/edNombre" android:hint="@string/nombre" /> <Button style="?android:attr/buttonStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/borrar" android:id="@+id/btnBorrar" /> <Button style="?android:attr/buttonStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/nuevo" android:id="@+id/btnNuevoCliente" /> </TableRow> <TableRow android:layout_width="match_parent" android:layout_height="match_parent"> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:inputType="textPersonName" android:ems="10" android:id="@+id/edApellido" android:hint="@string/apellido" /> <Button style="?android:attr/buttonStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/omitir" android:id="@+id/btnOmitir" android:layout_column="1" /> </TableRow> <TableRow android:layout_width="match_parent" android:layout_height="match_parent" > <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:inputType="number" android:ems="10" android:id="@+id/edCuenta" android:hint="@string/cuenta" /> </TableRow> <TableRow android:layout_width="match_parent" android:layout_height="match_parent"> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:inputType="phone" android:ems="10" android:id="@+id/edTelefono" android:hint="@string/telefono" /> </TableRow> </TableLayout> |
ParsearXML\app\src\main\res\layout\activity_tareasxml.xml
Comentar finalmente el layout activity_tareasxml.xml
, que define el layout de la Activity TareasXML.java
, y que implementa:
- Un control de tipo
EditText
para filtrar los datos del documento XML - Cuatro controles de tipo
Button
, encargados de cargar, filtrar, refrescar o crear un documento XML - Un control
ListView
, que listará la información del XML. - Además se implementa un control
Spinner
que mostrará los documentos creados en la memoria interna del dispositivo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout<em>width="match</em>parent" android:layout<em>height="match<em>parent" android:paddingLeft="@dimen/activity</em>horizontal</em>margin" android:paddingRight="@dimen/activity<em>horizontal</em>margin" android:paddingTop="@dimen/activity<em>vertical<em>margin" android:paddingBottom="@dimen/activity</em>vertical</em>margin" tools:context="com.academiaandroid.parsearxml.TareasXML" android:orientation="horizontal"> <TableLayout android:layout_width="match_parent" android:layout_height="match_parent"> <TableRow android:layout_width="match_parent" android:layout_height="match_parent"> <Button style="?android:attr/buttonStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/cargar" android:id="@+id/btnCargarDocumento" /> <Spinner android:layout_width="350dp" android:layout_height="wrap_content" android:id="@+id/spDoc" android:layout_column="1" android:spinnerMode="dropdown" /> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/imbtnActualizar" android:src="@drawable/actualizar" style="@style/Base.TextAppearance.AppCompat" android:contentDescription="@string/actualizar" android:layout_column="3" /> </TableRow> <TableRow android:layout_width="match_parent" android:layout_height="match_parent"> <Button style="?android:attr/buttonStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/buscar" android:id="@+id/btnFiltrarResultados" android:layout_column="0" /> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:inputType="text" android:ems="10" android:id="@+id/edFiltroResultado" android:hint="@string/filtro" android:layout_column="1" /> </TableRow> <TableRow android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:text="@string/documento" android:id="@+id/textView" android:textStyle="bold" android:layout_column="0" /> <Button style="?android:attr/buttonStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/nuevo_cliente" android:id="@+id/btnNuevo" android:layout_column="1" /> </TableRow> <TableRow android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:layout_width="200dp" android:layout_height="350dp" android:id="@android:id/list" android:layout_column="0" /> </TableRow> </TableLayout> |
ClienteBiblioteca\app\src\main\res\layout\item.xml
Layout que define la vista personalizada de cada uno de los elementos que se mostrarán en el control ListView
, y que estará formado por cuatro controles de tipo TextView
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
<?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout<em>width="match</em>parent" android:layout<em>height="match</em>parent"> <TableRow android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/sin_datos" android:id="@+id/tvItemNombre" /> </TableRow> <TableRow android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/sin_datos" android:id="@+id/tvItemApellido" /> </TableRow> <TableRow android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceSmall" android:text="@string/sin_datos" android:id="@+id/tvItemCuenta" /> </TableRow> <TableRow android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceSmall" android:text="@string/sin_datos" android:id="@+id/tvItemTelefono" /> </TableRow> |
Descarga del Proyecto
DownloadEn la siguiente publicación explicaremos el proyecto y veremos el funcionamiento de la aplicación en un video.