B4A en español - Juan Antonio Villalpando
(BASIC4Android)
-- Tutorial de B4A --
Volver al índice del tutorial
____________________________
73.- Librería XMLSAX.
La librería XmlSax se utiliza para "sacar" los datos de los archivos XML.
Es una librería con pocos parámetros pero algo complicadad de utilizar.
En este tutorial he puesto algunos ejemplos de aprendizaje.
En esta web podemos comprobar si la síntasis de nuestro archivo XML es correcto.
Librería XMLSax
_______________________________
1º Ejemplo.
Los XML son archivos que contienen una información ordenada según ciertas reglas. Conociendo esas reglas podemos obtener los datos guardados en esa información. Es algo parecido a una base de datos, pero con información menos "cuadrada".
Vamos a trabajar con este archivo:
Copia y pega este código en la carpeta Files, con el nombre: archivo.xml |
<clase>
<alumno><nombre>Juan</nombre><apellido>Villa</apellido><edad>22</edad></alumno>
<alumno><nombre>Antonio</nombre><apellido>Laso</apellido><edad>23</edad></alumno>
<alumno><nombre>Luis</nombre><apellido>Diaz</apellido><edad>24</edad></alumno>
<alumno><nombre>Carlos</nombre><apellido>Martin</apellido><edad>25</edad></alumno>
</clase> |
|
- Necesitamos un "layout" con un ListView1 y un Label1.
- También debemos activar la librería: XmlSax
- Cuando pulsemos sobre un nombre, se nos mostrará su edad. |
Este es el código. |
Sub Process_Globals
' Juan Antonio Villalpando
' juana1991@yahoo.com
Dim parser As SaxParser
Type alumnado(nombre As String, apellido As String, edad As String)
Dim losalumnos As List
End Sub
Sub Globals
Dim ListView1 As ListView
Dim Label1 As Label
Dim nombre, apellido, edad As String
End Sub
Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("layout")
If FirstTime Then
parser.Initialize
Dim In As InputStream
In = File.OpenInput(File.DirAssets, "archivo.xml")
losalumnos.Initialize
parser.Parse(In, "clase")
In.Close
End If
' Dim c As alumnado
' c = losalumnos.Get(2) ' El tercer elemento aparece en la pestaña Log
' Log(c.nombre & " " & c.apellido & " " & c.edad)
End Sub
Sub clase_StartElement (Uri As String, Name As String, Attributes As Attributes)
If Name = "alumno" Then
Dim c As alumnado
c.Initialize
losalumnos.Add(c)
End If
End Sub
Sub clase_EndElement (Uri As String, Name As String, Text As StringBuilder)
Dim c As alumnado
c = losalumnos.Get(losalumnos.Size - 1)
Select Name
Case "nombre"
c.nombre = Text
Case "apellido"
c.apellido = Text
Case "edad"
c.edad = Text
End Select
If Name = "nombre" Then
ListView1.AddSingleLine(c.nombre)
End If
End Sub
' EN ESTE CASO EL LISTVIEW1 TIENE DOS LÍNEAS, PERO NO FUNCIONA CUANDO PULSAMOS
'Sub clase_EndElement (Uri As String, Name As String, Text As StringBuilder)
' If parser.Parents.IndexOf("alumno") > -1 Then
' If Name = "nombre" Then
' nombre = Text.ToString
' Else If Name = "apellido" Then
' apellido = Text.ToString
' ListView1.AddTwoLines(nombre, apellido)
' End If
' End If
'End Sub
Sub ListView1_ItemClick (Position As Int, Value As Object)
Dim c As alumnado
c = losalumnos.Get(Position)
Label1.Text = c.edad
End Sub
|
_______________________________
2º Ejemplo.
Este ejemplo está sacado directamente de los foros de Basic4Android,
trata de obtener una página web de noticias con contenido en XML (http://news.yahoo.com/rss/world)
y sacar ese contenido a un ListView.
Se necesitan las librerías: HTTP, Phone y XmlSax.
Tambien un Layout llamado "Main"
Activity.LoadLayout("Main"), que contiene un ListView llamado RSS.
Copia y pega este código. |
Sub Process_Globals
Dim Parser As SaxParser
Dim web As PhoneIntents
Dim hc As HttpClient
Dim req As HttpRequest
End Sub
Sub Globals
Dim RSS As ListView
Dim Title, Link, PubDate, Description As String
Dim BufferText As String
Dim NewFeed As String
End Sub
Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("Main")
'Here we check if a feed exists and grab its contents to compare it
If File.Exists(File.DirDefaultExternal, "RSS.xml") = True Then
BufferText = File.ReadString(File.DirDefaultExternal, "RSS.xml")
End If
RSS.Width = 100%x
RSS.Height = 100%y
Parser.Initialize
hc.Initialize("hc")
req.InitializeGet("http://news.yahoo.com/rss/world")
hc.Execute(req, 1)
End Sub
Sub Activity_Resume
End Sub
Sub Activity_Pause(UserClosed As Boolean)
End Sub
'##########################
'######## Controls ########
'##########################
Sub RSS_ItemClick(Position As Int, Value As Object)
StartActivity(web.OpenBrowser(Value)) 'Open the browser with the link
End Sub
'############################
'######## Fetch Data ########
'############################
Sub hc_ResponseSuccess(Response As HttpResponse, TaskId As Int)
Response.GetAsynchronously("GetRSS",File.OpenOutput(File.DirDefaultExternal,"RSS.xml", False), True, TaskId)
End Sub
Sub hc_ResponseError(Response As HttpResponse, Reason As String, StatusCode As Int, TaskId As Int)
If Response <> Null Then
Msgbox("Error: " & Response.GetString("UTF8"), "Connection Error")
Response.Release
End If
End Sub
Sub GetRSS_StreamFinish(Success As Boolean, TaskId As Int)
If Success = False Then
Msgbox(LastException.Message, "Error")
Return
End If
Dim In As InputStream
In = File.OpenInput(File.DirDefaultExternal, "RSS.xml")
Parser.Parse(In, "Parser")
In.Close
'Here we compare if the feed has something new
NewFeed = File.ReadString(File.DirDefaultExternal, "RSS.xml")
If BufferText.Length <> NewFeed.Length Then
Msgbox("There's something new", "")
End If
End Sub
'##########################
'######## Routines ########
'##########################
Sub Parser_StartElement(Uri As String, Name As String, Attributes As Attributes)
End Sub
Sub Parser_EndElement(Uri As String, Name As String, Text As StringBuilder)
If Parser.Parents.IndexOf("item") > -1 Then
If Name = "title" Then
Title = Text.ToString
Else If Name = "link" Then
Link = Text.ToString
Else If Name = "pubdate" Then
PubDate = Text.ToString
Else If Name = "description" Then
Description = Text.ToString
End If
End If
If Name = "item" Then
RSS.TwoLinesLayout.Label.Gravity = Gravity.TOP
RSS.TwoLinesLayout.Label.TextSize = 9dip
RSS.TwoLinesLayout.Label.Height = 140dip
RSS.TwoLinesLayout.ItemHeight = 140dip
RSS.TwoLinesLayout.SecondLabel.TextSize = 8dip
RSS.TwoLinesLayout.SecondLabel.Height = 140dip
RSS.AddTwoLines2(Title, Description, Link)
End If
End Sub
|
_______________________________
3º Ejemplo.
En este caso tenemos el siguiente archivo en la carpeta Files:
Copia y pega este código en la carpeta Files, con el nombre: archivo.xml |
<clase>
<alumno nombre="Juan" apellido="Villa" telefono="123456" web="http://hola.com"/>
<alumno nombre="Antonio" apellido="Luque" telefono="334455" web="http://adios.com"/>
<alumno nombre="Luis" apellido="Leal" telefono="557788" web="http://buenas.com"/>
<alumno nombre="Eva" apellido="Luz" telefono="442266" web="http://bien.com"/>
</clase>
|
En este caso, el archivo está formado por elementos, es distinto al que vimos en el ejemplo 1.
Para obtener los elementos, que aquí se llaman atributos, situamos el código en: Sub resultado_StartElement
En nuestro caso vamos a obtener el elemento 2, que corresponde al telefono: Attributes.GetValue(2), "")
Debemos habilitar la librería XmlSax.
Copia y pega este código. |
Sub Process_Globals
' Juan Antonio Villalpando
' juana1991@yahoo.com
Dim parser As SaxParser
End Sub
Sub Globals
End Sub
Sub Activity_Create(FirstTime As Boolean)
If FirstTime Then
parser.Initialize
Dim In As InputStream
In = File.OpenInput(File.DirAssets, "archivo.xml")
parser.Parse(In, "resultado")
In.Close
End If
End Sub
Sub resultado_StartElement (Uri As String, Name As String, Attributes As Attributes)
Msgbox("Uri=" & Uri & CRLF & "Name=" & Name & CRLF & "Elemento=" & Attributes.GetValue(2), "")
End Sub
Sub result_EndElement (Uri As String, Name As String, Text As StringBuilder)
End Sub
|
_______________________________
4º Ejemplo.
En el mismo foro podemos bajar este ejemplo bastante didáctido y aconsejable: Xml.zip. Cópialo directamente del foro o del enlace.
- (Este es otro ejemplo del foro, no lo he probado)
_______________________________
5º Ejemplo.
En este caso tenemos el siguiente archivo en la carpeta Files:
Copia y pega este código en la carpeta Files, con el nombre: archivo.xml |
<clase>
<alumno nombre="Juan" apellido="Villa" edad="22" ciudad="Cadiz">
<medidas peso="80" altura="1.80" />
</alumno>
<alumno nombre="Antonio" apellido="Garcia" edad="33" ciudad="Puerto Real">
<medidas peso="76" altura="1.74" />
</alumno>
<alumno nombre="Luis" apellido="Lopez" edad="44" ciudad="Grazalema">
<medidas peso="79" altura="1.71" />
</alumno>
<alumno nombre="Carlos" apellido="Martin" edad="55" ciudad="Jerez">
<medidas peso="71" altura="1.68" />
</alumno>
</clase>
|
La información se obtiene en la parte Logs, la pestaña situada abajo-derecha del programa.
Este código tenemos que depurarlo porque aparecen líneas repetidas.
Copia y pega este código. |
Sub Process_Globals
' Juan Antonio Villalpando
' juana1991@yahoo.com
Dim parser As SaxParser
Type alumnado(nombre As String, apellido As String, edad As String, ciudad As String, peso As String, altura As String)
Dim Listadealumnos As List
End Sub
Sub Globals
Dim Elemento As alumnado
End Sub
Sub Activity_Create(FirstTime As Boolean)
If FirstTime Then
parser.Initialize
Dim In As InputStream
In = File.OpenInput(File.DirAssets, "archivo.xml")
Listadealumnos.Initialize
parser.Parse(In, "Parser")
In.Close
End If
End Sub
Sub Parser_StartElement (Uri As String, Name As String, Attributes As Attributes)
If Name = "alumno" Then
Dim Elemento As alumnado Elemento.Initialize
Elemento.nombre = Attributes.GetValue2("", "nombre")
Elemento.apellido = Attributes.GetValue2("", "apellido")
Elemento.edad = Attributes.GetValue2("", "edad")
Elemento.ciudad = Attributes.GetValue2("", "ciudad")
' End If
Else If Name = "medidas" Then
Elemento.peso = Attributes.GetValue2("", "peso")
Elemento.altura = Attributes.GetValue2("", "altura")
End If
Listadealumnos.Add(Elemento)
Log("Nombre " & Elemento.nombre &" " & " Peso " & Elemento.peso &" " & " Altura " & Elemento.altura)
End Sub
Sub Parser_EndElement (Uri As String, Name As String, Text As StringBuilder)
End Sub
|
_______________________________
6º Ejemplo.
Este ejemplo también está sacado directamente del foro, concretamente de este envío.
Lo he puesto aquí para correguir el elemento </day>, pues le faltaba la barra de fin de elemento en el envío y para situar el ListView.
En este caso tenemos el siguiente archivo en la carpeta Files:
Copia y pega este código en la carpeta Files, con el nombre: 1.xml |
<data>
<day>
<name>Monday</name>
<activities>
<activity>
<name>Wash car</name>
<timeFrom>12:00</timeFrom>
<timeTo>12:30</timeTo>
</activity>
<activity>
<name>Sleep</name>
<timeFrom>14:00</timeFrom>
<timeTo>15:00</timeTo>
</activity>
</activities>
</day>
<day>
<name>Wednesday</name>
<activities>
<activity>
<name>Eat</name>
<timeFrom>12:00</timeFrom>
<timeTo>12:30</timeTo>
</activity>
<activity>
<name>Sleep</name>
<timeFrom>14:00</timeFrom>
<timeTo>15:00</timeTo>
</activity>
</activities>
</day>
</data>
|
- Necesitamos un Layout llamado "layout" con un ListView con el nombre LV_Test.
Dim LV_Test As ListView
Activity.LoadLayout("layout")
- Además debemos copiar el archivo anterior 1.xml en la carpeta Files del proyecto y habilitar la librería XMLSax.
Copia y pega este código. |
Sub Process_Globals
Type Day(name As String, Activities As List)
Type Act(name As String, timeFrom As String, timeTo As String)
Dim parser As SaxParser
Dim MyDays As List
Dim tempDay As Day
Dim tempAct As Act
End Sub
Sub Globals
Dim LV_Test As ListView
End Sub
Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("layout")
parser.Initialize
MyDays.Initialize
Dim In As InputStream
In = File.OpenInput(File.DirAssets, "1.xml")
parser.Parse(In, "parser")
In.Close
Log(MyDays)
For i = 0 To MyDays.Size - 1
Dim d As Day
d = MyDays.Get(i)
LV_Test.AddTwoLines(d.name, "-")
For l = 0 To d.Activities.Size - 1
Dim a As Act
a = d.Activities.Get(l)
LV_Test.AddTwoLines(a.timeFrom, "-")
Next
Next
End Sub
Sub Parser_StartElement (Uri As String, Name As String, Attributes As Attributes)
If Name = "day" Then
Dim tempDay As Day 'this creates a new Day object
tempDay.Initialize
tempDay.Activities.Initialize
MyDays.Add(tempDay)
Else If Name = "activity" Then
Dim tempAct As Act
tempDay.Activities.Add(tempAct)
End If
End Sub
Sub Parser_EndElement (Uri As String, Name As String, Text As StringBuilder)
Select Name
Case "name"
If parser.Parents.IndexOf("activity") = -1 Then
'this is the day name
tempDay.Name = Text.ToString
Else
tempAct.Name = Text.ToString
End If
Case "timeFrom"
tempAct.timeFrom = Text.ToString
'complete other attributes
End Select
End Sub
|
________________________________
|