Comunidad de diseño web y desarrollo en internet online

Error al parsear un objeto en as3 con JSON

Citar            
MensajeEscrito el 20 Mar 2015 05:44 pm
Hola amigos, tengo el siguiente problema y no encuentro nada relacionado en internet


Tengo el siguiente objeto que lo recupero del servidor y al parsear me da error en la linea que contiene html

{
"serverInfo": {
"initialData": [
[
"37517",
"1",
"Documento",
"DOCUMENTO",
"0",
"1",
"<P ALIGN="LEFT"><FONT FACE="_sans" SIZE="11" COLOR="#000000" LETTERSPACING="0" KERNING="0">Documento. (sept.13)</FONT></P>",
"0"
]
],
"columnNames": [
"ref",
"cod",
"nom",
"tipdoc",
"brrdor",
"numcop",
"desdoc",
"tsd"
],
"totalCount": 29
}
}


Este es el error que me lanza el validador de jsonlint.com

Parse error on line 11:
... "<P ALIGN="LEFT"><FONT FACE="_s
-----------------------^
Expecting '}', ':', ',', ']'


Necesito parsear ese contenido intacto ya que luego lo meto en un text area mediante su propiedad htmlText.


var r:Object =JSON.parse('{"serverInfo":{"initialData":[["37517","1","Documento","DOCUMENTO","0","1","<P ALIGN="LEFT"><FONT FACE="_sans" SIZE="11" COLOR="#000000" LETTERSPACING="0" KERNING="0">Documento(sept.13)</FONT></P>","0"]],"columnNames":["ref","cod","nom","tipdoc","brrdor","numcop","desdoc","tsd"],"totalCount":29}}');


textarea.htmlText = r.serverInfo.initialData[0][6];

Agradeceria una ayudita Solis

Saludos

Por giskard

110 de clabLevel



Genero:Masculino  

Programador y diseñador web

firefox
Citar            
MensajeEscrito el 20 Mar 2015 07:56 pm
Tienes comillas afuera y adentro del HTML y eso quiebra el string. Usa comillas simples para los atributos HTML

"<P ALIGN='LEFT' ...etc

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 21 Mar 2015 12:01 pm
Gracias solis el lunes lo pruebo, yo ya estaba pensando en pasarle htmlentities a la cadena html en el servidor con php antes de introducirla en el objeto y enviarlo a flash, despues al recuperar el valor en flash decodificar las entidades html de nuevo.

Probare de encerrar el html con comillas simples primero a ver si funciona, si no probare con lo de htmlentite porque cambiar las dobles comillas de los atributos del html representaria un trabajo complicado en 400 mb de documentos.. e implicaria mas cambios de codigo en el editor html encargado de guardar los docs.

Gracias solis

Un saludo

Por giskard

110 de clabLevel



Genero:Masculino  

Programador y diseñador web

safari
Citar            
MensajeEscrito el 21 Mar 2015 12:01 pm
Gracias solis el lunes lo pruebo, yo ya estaba pensando en pasarle htmlentities a la cadena html en el servidor con php antes de introducirla en el objeto y enviarlo a flash, despues al recuperar el valor en flash decodificar las entidades html de nuevo.

Probare de encerrar el html con comillas simples primero a ver si funciona, si no probare con lo de htmlentite porque cambiar las dobles comillas de los atributos del html representaria un trabajo complicado en 400 mb de documentos.. e implicaria mas cambios de codigo en el editor html encargado de guardar los docs.

Gracias solis

Un saludo

Por giskard

110 de clabLevel



Genero:Masculino  

Programador y diseñador web

safari
Citar            
MensajeEscrito el 23 Mar 2015 09:11 pm
Hola de nuevo solisrag, ya solucione el problema, al final encontré la solución en la ayuda de php.net
solo tenía que escapar los caracteres reservados de JSON, para ello e usado la siguiente función

Código PHP :

 
addcslashes($r[$n], "\\\"\n\r\t/" . chr(8) . chr(12));


Por si a alguien le pica la curiosidad estoy actualizando una RIA de amfphp1.0 a la nueva versión y para no tener que tocar y actualizar tropecientas pantallas del lado del cliente estoy emulando la manera en que amfphp 1.0 devolvía los resultados ;) Dejo aquí la parte del código encargada de formar un objeto valido para as3 en formato json, por si a alguien le sirve.
Saludos y gracias solisrag
Hasta la proxima :)

Código PHP :

//...
if(gettype($res) == boolean){
  return $res;
}else{// is resource
  $numRows = mysqli_num_rows($res); 
  $resultset = array();
  while($r = mysqli_fetch_array($res,MYSQLI_NUM)){
    $len = count($r);
    for($n=0;$n<$len;$n++){
    $r[$n] =  addcslashes($r[$n], "\\\"\n\r\t/" . chr(8) . chr(12)); //Escapamos caractares reservados, formato JSON.
    }//End for($n=0;$n<$len;$n++){
    $resultset[] = '["'.implode('","', $r).'"]'; 
  }//End while($r = mysqli_fetch_array($res,MYSQLI_NUM)){ 
  $colNames = array();
  while($campos = mysqli_fetch_field($res)){
    $colNames[] = $campos->name;
  }//End while($campos = mysqli_fetch_field($res)){
 $obj = '{"serverInfo":{"initialData":['.implode(",", $resultset).'],"columnNames":["'.implode('","',  $colNames).'"],"totalCount":'.$numRows.'}}';
mysqli_free_result($res);
return $obj;
}//End else if(gettype($res) == boolean)
//...

Por giskard

110 de clabLevel



Genero:Masculino  

Programador y diseñador web

firefox
Citar            
MensajeEscrito el 23 Mar 2015 09:39 pm
Y por que usas JSON con amfphp ... justamente la idea de usar amf es beneficiarse de ese formato binario, para usar JSON no necesitas de amfphp .... entiendo entonces que lo que haces es dejar de usar amfphp

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 24 Mar 2015 02:49 pm
Hola solisarg, pues en principio sigo utilizando amfphp, te explico cómo recordaras con la versión 1 de amfphp podías enviar el resource de una consulta mysql directamente a flash desde donde podías acceder a los datos mediante objeto.serverInfo.initialData

Con la versión nueva de amfphp la 2.2 ya no funciona devolver un resource directamente, por lo que te tienes que encargar tu de formatear los datos antes de enviarlos a flash o por lo menos es lo que yo he entendido.

Pues bien yo con la versión 1 la estructura que tenia montada era una clase host que era la encargada de la conexión, las consultas y recuperar los datos devueltos por el servidor
Así por ejemplo en cada formulario tengo algo parecido a lo siguiente:

Código ActionScript :

import Host;
var host:Host = new Host();

host.call("sql.query",QueryEncrypted1,onRecivedData);
function onRecivedData(r:*):void{
   var datos:Array = r.serverInfo.initialData;
}


Teniendo como 10 o más llamadas por formulario de este tipo pero con consultas diferentes.

Código ActionScript :

host.call("sql.query",QueryEncrypted2,onRecivedData);


Pues bien mi idea es tocar solo la clase host para que siga devolviendo la misma estructura del objeto r.serverInfo.initialData a los formularios y no tener que estar modificando todas las consultas de todas las pantallas, que podría provocar más tiempo y mas probabilidad de errores.

Así que lo que he hecho es recuperar los datos de una consulta mysql y montar un objeto as3 igual que serverInfo.initialData desde php tal que asi:

Código PHP :

 
return "{"serverInfo":{"initialData":[["javier","vicente","..."]],"columnNames":["nombre","apellido1","apellido2"],"totalCount":1}}";

Cuál es el problema? que al recibir esa cadena como "STRING" en flash, e intentar convertirla en un objeto da error.

Código ActionScript :

var o:Object = '{"serverInfo":{"initialData":[["javier","vicente","..."]],"columnNames":["nombre","apellido1","apellido2"],"totalCount":1}}';

trace(o.serverInfo.initialData);

//Resultado-> ReferenceError: Error #1069: No se encontró la propiedad serverInfo en String y no hay ningún valor predeterminado. at Sint_fla::MainTimeline/frame1()

Si la misma cadena la creo de la siguiente manera omitiendo las comillas simples de cierre, flash crea el objeto correctamente, es curioso que por esa simple diferencia después no sea posible volver a convertir la cadena en un objeto sin usar un parser y si lo es lo desconozco.

Código ActionScript :

var o:Object = {"serverInfo":{"initialData":[["javier","vicente","..."]],"columnNames":["nombre","apellido1","apellido2"],"totalCount":1}}
trace(o.serverInfo.initialData); //Resultado-> javier,vicente,...
trace(o.serverInfo.initialData[0][0]); //Resultado-> javier

Así que buscando una solución lo único que encontré fue o hacerme una propia función para parsear el objeto o utilizar JSON por lo que para reiventar la rueda decidi utilizar JSON.

Utilizando JSON para convertir la cadena en un objeto no da error, si hay otra solución la desconozco.

Código ActionScript :

var o:Object = JSON.parse('{"serverInfo":{"initialData":[["javier","vicente","..."]],"columnNames":["nombre","apellido1","apellido2"],"totalCount":1}}');


En principio sigo utilizando amf para el envió y recepción de datos , pero para convertir el objeto recuperado en un objeto as3 utilizo JSON

Ya me diréis si he hecho una burrada muy grande :)

La cuestión es que solo he tenido que actualizar una clase y no 10.000 líneas de código de todos los formularios y de rebote otras clases relacionadas como las encargadas de rellenar los datagrids que están programadas dependiendo de la misma estructura del objeto r.serverInfo.columnNames, r.serverInfo.initialData o r.serverInfo.totalCount

Saludos Solisarg

Por giskard

110 de clabLevel



Genero:Masculino  

Programador y diseñador web

firefox
Citar            
MensajeEscrito el 24 Mar 2015 04:48 pm
El objetivo de amf (actionscipt message format) es pasar objetos nativos desde el servidor al cliente. Si parseas con JSON, usar amf es inútil porque justamente la ventaja de amf sobre cualquier otro método (JSON, XML, pares nombre/valor, etc) es que no necesitas parsear sino recorres objetos nativos.
Hace bastante que no trabajo con amf, pero recuerdo que cuando ya no se podía pasar el resource, lo que pasaba era el array asociativo (el que viene de mysql_fetch_array) que era recibido como una especia de recordset en AS3 que podría recorrer nativamente.
Entonces: si hacerlo asi lo mantiene andando y la performance es buena y tienes un montón de código ya hecho, listo. Pero usar objetos nativos es realmente el motivo por el que usamos amf, y pasarlo a JSON o cualquier otro formato de String invalida el objetivo mismo de usarlo

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 25 Mar 2015 12:11 am
Hola solis, yo qusiera pasar el objeto anterior de manera nativa, pero no se como hacerlo, supuestamete la cadena/string ya viaja bajo el formato amf binario, puesto que de eso se encarga amfphp en el momento que envia un resultado a flash, yo lo unico que hago es decodificar la cadena con json para poder tratarla como un objeto.

Como enviarias de manera nativa este objeto -> {nombre:"juan"}

Por cierto si se duplica este mensaje puede ser que la causa sea por postear con el movil.

Por giskard

110 de clabLevel



Genero:Masculino  

Programador y diseñador web

safari
Citar            
MensajeEscrito el 25 Mar 2015 12:43 pm
Tip: devuelves el array asociativo, mysqli_fetch_array
Recibes un array de objetos. Si usas Charles para sniffar la conexión, podrás ver que recibes un array de objetos y todas sus propiedades. La ventaja es que no hay que parsear nada. Para el caso de Nombre Juan lo que envías es

array("nombre"=>"Juan");

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 25 Mar 2015 04:35 pm
Hola solis, tienes razon esta mañana me puesto a darle un par de vueltas mas y leiendo info e visto lo que comentas en este ultimo post, e echo unas pruebas y funciona perfecto, es lo que pasa por ser un negado me complico mas la vida :/

Ahora puedo recorrer el objeto devuelto desde flash con;

Código ActionScript :

for(var key:String in object) { 
trace(key);
 }

Así puedo sacar el nombre de las columnas y los datos relacionados para montar el objeto obj.serverInfo.initialData directamente en flash en vez de en php y asi no tener que usar JSON.

Gracias solis ;)

Por giskard

110 de clabLevel



Genero:Masculino  

Programador y diseñador web

firefox
Citar            
MensajeEscrito el 25 Mar 2015 10:30 pm
Hola de nuevo, finalmente resolví el tema enviando el objeto completo de manera nativa desde php en vez de como string.

Ahora ya no necesito JSON y e solucionado todos los problemas de caracteres de un plumazo.

Dejo el código por si a alguien le resulta de utilidad


Código PHP :

//$res es el resource
if(gettype($res) == boolean){
  return $res;
}else{
 $numRows = mysqli_num_rows($res); 
 $resultset = array();
while($r = mysqli_fetch_array($res,MYSQLI_NUM)){ 
 $resultset[] = $r;
}
 $colNames = array();
    while($campos = mysqli_fetch_field($res)){
       $colNames[] = $campos->name;
    return (object) array('serverInfo' => (object) array('initialData' => $resultset,'columnNames' => $colNames,'totalCount' => $numRows));
  }
}


Un saludo solis

Por giskard

110 de clabLevel



Genero:Masculino  

Programador y diseñador web

firefox

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.