Página 1 de 1

_XMLGetAttrib y Valenbisi (servicio de bicicletas públicas)

Publicado: 07 Ene 2011, 17:14
por jamaro
Hola de nuevo a todos:

Ayer estuve leyendo este artículo: http://boozox.net/boozox/api-de-valenbi ... jcdeacaux/ , donde el autor explica cómo ha utilizado un par de páginas .xml: http://www.valenbisi.es/service/carto y http://www.valenbisi.es/service/station ... m_estacion , para montar la página http://bicivalencia.com/ donde se muestra un mapa con las estaciones de Valenbisi.

Me picó la curiosidad y pensé en hacer una aplicación que me mostrara en la bandeja de sistema las bicicletas que hay disponibles en la estación más cercana a casa (podría "vigilar" varias estaciones cercanas para así saber cuántas bicicletas hay en cada una y saber a cuál acudir cuando salga de casa).

De momento, en el ejemplo que os pongo, la aplicación se ejecuta una única vez (la idea sería que estuviera residente y cada cierto tiempo actualizara los datos); la estación se introduce con un "inputbox" (se podría poner el número de la estación dentro de la aplicación o en un .ini para personalizarlo según el gusto del usuario); y el resultado lo muestra con un "msgbox" (la idea, como dije antes, sería mostrarlo en la bandeja de sistema con "traytip")

Siguiendo el ejemplo del hilo:
http://www.autoitscript.com/forum/topic/97466-xml-read/
y utilizando su código, he podido leer correctamente los datos de la página:
http://www.valenbisi.es/service/station ... m_estacion

Pero el problema lo tengo a la hora de leer y utilizar los datos de la página:
http://www.valenbisi.es/service/carto

El motivo del mensaje es que no he conseguido utilizar correctamente la función _XMLGetAttrib, de la librería XMLDOMWrapper.au3 que se puede encontrar en: http://www.autoitscript.com/forum/topic ... lgetattrib

He visto muchos ejemplos de su uso, pero no consigo hacerlo funcionar para la página: http://www.valenbisi.es/service/carto (tampoco lo consigo con los ejemplos de internet)

En todas las pruebas (queda parte del código en el ejemplo entre comentarios #cs y #ce) el valor que obtengo con _XMLGetAttrib es -1, y el error 2 = No object.

Al final he obtenido el resultado que deseaba por otros medios, siguiendo el hilo:
http://www.autoitscript.com/forum/topic ... ntry712710
donde, en el mensaje #10 proponen utilizar _StringBetween

¿Alguien sabe si se puede aplicar _XMLGetAttrib en el código indicado y cómo hacerlo?
Lo que quisiera obtener es el valor de "address" cuando el valor de "number" sea igual al de $num_estacion que he definido al principio del código.


Como en otras ocasiones, gracias por la ayuda ;-)

Código: Seleccionar todo

; Lee datos de estación de Valenbisi
;
; http://www.valenbisi.es/service/stationdetails/num_estacion
;	Contiene los datos de la estación "num_estacion" relativos al número de bornetas totales, libres y número de bicicletas libres
;
; http://www.valenbisi.es/service/carto
; 	Contiene listado de estaciones con su información (nombre, número, dirección, latitud, longitud,...)

#include <_XMLDomWrapper.au3>
#include <File.au3>

Global $oXML = ObjCreate("Microsoft.XMLHTTP")

;-------------------------------------------------------------------------------------------
; Lectura de datos (bicis y bornetas libres) de una estación num_estacion
;-------------------------------------------------------------------------------------------
$num_estacion=InputBox("Número de estación","Indique el número de estación que desea leer"); Número de estación a leer

$oXML.Open("GET", "http://www.valenbisi.es/service/stationdetails/"&$num_estacion, 0)
$oXML.Send

Global $sFile = _TempFile(@TempDir, '~', '.xml')
FileWrite($sFile, $oXML.responseText)

$file = FileRead($sFile)
$file = StringReplace($file, @LF, '')
$file = StringSplit($file, @CR, 1)

$Valenbisi_disponibles=XMLget($file, 'station\available')
$Valenbisi_libres=XMLget($file, 'station\free')
$Valenbisi_totales=XMLget($file, 'station\total')


$DisponibilidadEstacion = $Valenbisi_disponibles & @TAB & "Bicis disponibles"& @crlf &  $Valenbisi_libres & @TAB & "Bornetas libres" & @CRLF & $Valenbisi_totales & @TAB & "Bornetas totales"

;MsgBox(0, 'Estación ' & $num_estacion & ' de Valenbisi' , $Valenbisi_disponibles & @TAB & "Bicis disponibles"& @crlf &  $Valenbisi_libres & @TAB & "Bornetas libres" & @CRLF & $Valenbisi_totales & @TAB & "Bornetas totales")
FileDelete($sFile)
;-------------------------------------------------------------------------------------------


;-------------------------------------------------------------------------------------------
; Lectura de datos (dirección) una estación num_estacion
;-------------------------------------------------------------------------------------------

	$oXML.Open("GET", "http://www.valenbisi.es/service/carto", 0)
	$oXML.Send
	Global $sFile1 = _TempFile(@TempDir, '~', '.xml')
	FileWrite($sFile1, $oXML.responseText)
	$file1 = FileRead($sFile1)

		;----------------------------------------
		; Prueba con _StringBetween
		;----------------------------------------
		#Include <String.au3>
		#include <Array.au3>

		;ConsoleWrite($File1)
		Local $aArray1 = _StringBetween($File1,'number=','address')	; Campo con número de estación
		Local $aArray2 = _StringBetween($File1,'fullAddress="','" lat')	; Campo con dirección de la estación
			; _ArrayDisplay($aArray1, 'Datos encontrados')
			$Indice=_ArraySearch($aArray1,'"'& $num_estacion &'"',0,0,0,1)	; 0,0,0,1 Búsqueda parcial
			Local $aArray3 = _StringBetween($aArray1[$indice],'"','"')
			;$TextoEstacion = "Índice: " & $Indice & @crlf & "Estación: " & $aArray3[0] & @crlf &"Dirección: "& $aArray2[$indice]
			msgbox(0,"Estación: "& $num_estacion & " de Valenbisi - Dirección: " & $aArray2[$indice],$DisponibilidadEstacion)
		;--------------------


		;--------------------------------------------------------------------------------
		; Prueba con _XMLGetAttrib - Sólo devuelve valor -1
		;--------------------------------------------------------------------------------

		#cs     ; Prueba 1 con _XMLGetAttrib
		$file1 = _XMLFileOpen($sfile1)
		;_XMLGetAllAttrib ( strXPath, ByRef aName, ByRef aValue, strQry = "" ) 
		; $sXPath = '//bots/bot[@fight_id = "0" and @level = "3" and @sk = "2015"]'
		;ConsoleWrite(_XMLGetAllAttrib ( $file1, "//carto/markers/marker name", $num_estacion, "" ) )

		;$sXPath='//carto/markers/marker[@number="63"]'
		$sXPath='//carto/markers/marker[1]'
		ConsoleWrite("Valor obtenido con _XMLGetAttrib: " &_XMLGetAttrib($sXPath, 'name') & @CRLF & " Error: " & @error & @CRLF)
		#ce


		#cs     ; Prueba 2 con _XMLGetAttrib
		$file1 = _XMLFileOpen($sfile1)
		$nodesArray = _XMLSelectNodes("//markers/@*")

		For $i = 0 to $nodesArray[0] -1
		$test = _XMLGetAttrib("//markers[" & $i+1 & "]", "name")
		ConsoleWrite($test & @CRLF)
		Next
		#ce

	FileDelete($sFile1)

;-------------------------------------------------------------------------------------------


Func XMLget($file, $Path); XMLget($file,'adc_database\currentconditions\realfeel')
    $Path = StringSplit($Path, '/\|', 0)
    $lastline = 0
    For $lvl = 1 To $Path[0] Step 1
        For $line = $lastline To $file[0] Step 1
            $lastline = $line
            $hstart = StringInStr($file[$line], '<' & $Path[$lvl] & '>', 0)
            $hstarta = StringInStr($file[$line], '<' & $Path[$lvl] & ' ', 0)
            If $hstart Or $hstarta Then
                If $lvl == $Path[0] Then
                    If $hstart Then
                        $end = StringInStr($file[$line], '</' & $Path[$lvl] & '>', 0)
                        If $end Then
                            $hstart = $hstart + StringLen('<' & $Path[$lvl] & '>')
                            Return StringMid($file[$line], $hstart, $end - $hstart)
                        EndIf
                    EndIf
                    If $hstarta Then
                        $end = StringInStr($file[$line], '/>', 0)
                        If $end Then
                            $hstarta = $hstarta + StringLen('<' & $Path[$lvl] & ' ')
                            $return = StringMid($file[$line], $hstarta, $end - $hstarta)
                            Return $return
                        EndIf
                        $ends = StringInStr($file[$line], '>', 0)
                        If $ends Then
                            $hstart = $ends + 1
                            $end = StringInStr($file[$line], '</' & $Path[$lvl] & '>', 0)
                            If $end Then
                                $return = StringMid($file[$line], $hstart, $end - $hstart)
                                Return $return
                            EndIf
                        EndIf
                    EndIf
                EndIf
                ContinueLoop 2
            EndIf
        Next
        If $line == $file[0] Then ExitLoop
    Next
    Return 'not found'
EndFunc ;==>XMLget

Re: _XMLGetAttrib y Valenbisi (servicio de bicicletas públicas)

Publicado: 07 Ene 2011, 22:51
por jamaro
Parece que el problema no estaba con _XMLGetAttrib sino que no estaba usando correctamente la función _XMLFileOpen.

En el código que adjunto ahora se ha utilizado _XMLLoadXML en lugar de _XMLFileOpen.

Código: Seleccionar todo

; Lee datos de estación de Valenbisi según explicación en
; http://boozox.net/boozox/api-de-valenbisi-servicio-de-jcdeacaux/
;
;
; http://www.valenbisi.es/service/stationdetails/num_estacion
;	Contiene los datos de la estación "num_estacion" relativos al número de bornetas totales, libres y número de bicicletas libres
;
; http://www.valenbisi.es/service/carto
; 	Contiene listado de estaciones con su información (nombre, número, dirección, latitud, longitud,...)

#include <_XMLDomWrapper.au3>
#include <File.au3>

Global $oXML = ObjCreate("Microsoft.XMLHTTP")

;-------------------------------------------------------------------------------------------
; Lectura de datos (bicis y bornetas libres) de una estación num_estacion
;-------------------------------------------------------------------------------------------
$num_estacion=InputBox("Número de estación","Indique el número de estación que desea leer"); Número de estación a leer

$oXML.Open("GET", "http://www.valenbisi.es/service/stationdetails/"&$num_estacion, 0)
$oXML.Send
Global $sFile = _TempFile(@TempDir, '~', '.xml')
FileWrite($sFile, $oXML.responseText)

$file = FileRead($sFile)
$file = StringReplace($file, @LF, '')
$file = StringSplit($file, @CR, 1)

$Valenbisi_disponibles=XMLget($file, 'station\available')
$Valenbisi_libres=XMLget($file, 'station\free')
$Valenbisi_totales=XMLget($file, 'station\total')

$DisponibilidadEstacion = $Valenbisi_disponibles & @TAB & "Bicis disponibles"& @crlf &  $Valenbisi_libres & @TAB & "Bornetas libres" & @CRLF & $Valenbisi_totales & @TAB & "Bornetas totales"

;MsgBox(0, 'Estación ' & $num_estacion & ' de Valenbisi' , $Valenbisi_disponibles & @TAB & "Bicis disponibles"& @crlf &  $Valenbisi_libres & @TAB & "Bornetas libres" & @CRLF & $Valenbisi_totales & @TAB & "Bornetas totales")
FileDelete($sFile)
;-------------------------------------------------------------------------------------------

;-------------------------------------------------------------------------------------------
; Lectura de datos (dirección) una estación num_estacion
;-------------------------------------------------------------------------------------------
	$oXML.Open("GET", "http://www.valenbisi.es/service/carto", 0)
	$oXML.Send
	Global $sFile1 = _TempFile(@TempDir, '~', '.xml')
	FileWrite($sFile1, $oXML.responseText)
	$file1 = FileRead($sFile1)

	$fileXML=_XMLLoadXML($file1)
	$sXPath='//carto/markers/marker[@number="'& $num_estacion &'"]'
	$direccion_estacion=_XMLGetAttrib($sXPath, 'address')
	ConsoleWrite("Valor obtenido con _XMLGetAttrib: " & $direccion_estacion & @CRLF & " Error: " & @error & @CRLF)
	Select
		case $ValenBisi_disponibles=0
			msgbox(0,"AVISO","No quedan bicicletas en la estación " & $num_estacion & " " & $direccion_estacion)
		case $ValenBisi_disponibles>=1 and $ValenBisi_disponibles<5
			msgbox(0,"AVISO","Quedan menos de 5 bicicletas en la estación " & $num_estacion & " " & $direccion_estacion)
	EndSelect
	
	msgbox(0,"Estación: "& $num_estacion & " de Valenbisi - Dirección: " & $direccion_estacion,$DisponibilidadEstacion)
	FileDelete($sFile1)
;--------------------------------------------------------------------------------


;-------------------------------------------------------------------------------------------
; http://www.autoitscript.com/forum/topic/97466-xml-read/
Func XMLget($file, $Path); XMLget($file,'adc_database\currentconditions\realfeel')
    $Path = StringSplit($Path, '/\|', 0)
    $lastline = 0
    For $lvl = 1 To $Path[0] Step 1
        For $line = $lastline To $file[0] Step 1
            $lastline = $line
            $hstart = StringInStr($file[$line], '<' & $Path[$lvl] & '>', 0)
            $hstarta = StringInStr($file[$line], '<' & $Path[$lvl] & ' ', 0)
            If $hstart Or $hstarta Then
                If $lvl == $Path[0] Then
                    If $hstart Then
                        $end = StringInStr($file[$line], '</' & $Path[$lvl] & '>', 0)
                        If $end Then
                            $hstart = $hstart + StringLen('<' & $Path[$lvl] & '>')
                            Return StringMid($file[$line], $hstart, $end - $hstart)
                        EndIf
                    EndIf
                    If $hstarta Then
                        $end = StringInStr($file[$line], '/>', 0)
                        If $end Then
                            $hstarta = $hstarta + StringLen('<' & $Path[$lvl] & ' ')
                            $return = StringMid($file[$line], $hstarta, $end - $hstarta)
                            Return $return
                        EndIf
                        $ends = StringInStr($file[$line], '>', 0)
                        If $ends Then
                            $hstart = $ends + 1
                            $end = StringInStr($file[$line], '</' & $Path[$lvl] & '>', 0)
                            If $end Then
                                $return = StringMid($file[$line], $hstart, $end - $hstart)
                                Return $return
                            EndIf
                        EndIf
                    EndIf
                EndIf
                ContinueLoop 2
            EndIf
        Next
        If $line == $file[0] Then ExitLoop
    Next
    Return 'not found'
EndFunc ;==>XMLget