Problemilla libxml2

Buenas compañeros,

Os cuento, estoy trabajando con libxml2 para almacenar unos datos de una aplicación, en concreto los datos de una agenda. Intento que estos datos se almacenen en UTF-8.

El problema que me estoy encontrando es que, inicialmente cargo el fichero xml con los datos en UTF-8, con kate le estoy indicando el encoding, y tenga acentos o no lo carga sin problemas. Pero cuando realizo cambios y guardo los datos de nuevo en el fichero, si le he metido algún acento, me falla al cargar la agenda en la siguiente ejecución.

No sé si me estoy explicando bien.

Mis locales son:

LANG=es_ES@euro
LC_CTYPE="es_ES@euro"
LC_NUMERIC="es_ES@euro"
LC_TIME="es_ES@euro"
LC_COLLATE="es_ES@euro"
LC_MONETARY="es_ES@euro"
LC_MESSAGES="es_ES@euro"
LC_PAPER="es_ES@euro"
LC_NAME="es_ES@euro"
LC_ADDRESS="es_ES@euro"
LC_TELEPHONE="es_ES@euro"
LC_MEASUREMENT="es_ES@euro"
LC_IDENTIFICATION="es_ES@euro"
LC_ALL=es_ES@euro


¿Es esto un impedimento para guardar los datos en UTF-8? Si lo fuese, no me importaría almacenar los datos en iso-8859-15.

A la hora de crear el doc xml y guardarlo, hago lo siguiente:

xmlSwitchEncoding(NULL, XML_CHAR_ENCODING_UTF8);
xmlDocPtr doc = NULL;
xmlNodePtr root_node = NULL;

doc = xmlNewDoc(BAD_CAST "1.0");
root_node = xmlNewNode(NULL, BAD_CAST "agenda");
xmlDocSetRootElement(doc, root_node);

xmlCreateAgenda(root_node, agenda);
xmlSaveFormatFileEnc(filename.c_str(), doc, "UTF-8", 1);
xmlFree(doc);


¿Estoy haciendo algo mal? Quizá tenga que hacer algún tipo de "casting" de la codificación de las cadenas a la hora de guardarlas, no sé. La verdad es que es la primer avez que uso está biblioteca y estoy un pelín perdido. Por otra parte, esa función xmlCreateAgenda es mía, se encarga de ir creando la jerarquía de nodos para guardar la agenda en el fichero.


No sé si me he explicado bien y/o he aportado suficiente info. En cualquier caso, si son necesarios más datos, avisadme ;-)


Espero que alguien me pueda ayudar,
Muchas gracias :-)

Saludos

[EDITO]: Se me olvidaba, el error:

agenda.xml:9: parser error : Input is not proper UTF-8, indicate encoding !
Bytes: 0xE9 0x3C 0x2F 0x6E
José
^


ese circunflejo se supone que va debajo de é
¿ El error ocurre tras tocarlo con kate ? ¿ O con el documento TAL CUAL lo guarda libxml2 ?

BTW, ¿ realmente quieres usar BAD_CAST ? Mira la implementación y luego decide :)

- ferdy
No, con kate me aseguro que el fichero es UTF-8 [*] y lo carga sin problemas. El error me viene tras guardarlo con libxml y cerrar la aplicación; me peta al cargar la agenda cuando vuelvo a abrir la aplicación (solo si hay acentos).

Voy a ver el BAD_CAST

Gracias ferdy ;)


Saludos

[*] cuando uno no recuerda un modo mejor de hacerlo, lo hace con lo que se le ocurre :-P (cualquier sugerencia será bienvenida)


Edito: No he conseguido entender el significado del BAD_CAST ni encontrar solución al problema. La verdad es que la documentación de xmlsoft.org me parece algo confusa (será la novatada). Mañana seguiré probando.
Para comprobar el encoding de un fichero puedes usar file:
josu@arcueid ~ $ file a
a: UTF-8 Unicode text
Y si lo que quieres es convertirlo de otro encoding a UTF-8, puedes usar vim
:set fileencoding=utf8

Agur
Sospecho que xmlCreateAgenda tiene la culpa. Si puedo verla podré echarte un cable.



Si, la documentación de libxml2 es MALA.
Si, libxml2 te morderá los huevos si te descuidas.
Si, los tipos 'Ptr' son para q1nc34ñ3r4s. ¡ C ya tiene punteros !



- ferdy
Vale, me alegro que lo de la doc no sea solo percepción mía.

Realmente la chicha no está en esa función. Te pego el código de los xmlNewTextChild o xmlNewTextChildNode que supongo que serán los problemáticos. Un ejemplo (todos son similares):

xmlNewTextChild(node, NULL, /*BAD_CAST*/ (xmlChar*)"dir_correo", /*BAD_CAST*/ (xmlChar*) (*s_iter).c_str());


en el código se observa que usaba BAD_CAST, lo comenté y probé haciendo castings de las cadenas que le pasaba (intento un poco a ciegas, ya que como he comentado ando perdido). (*s_iter) es un string de la STL.

Yo también creo que el problema está en esto o en el código que he pegado en el primer post. Si es necesario te paso todo el código para guardar la agenda, que no llega a 100 lineas.

Gracias de nuevo ferdy, te he agregado en jabber, por si crees que es más fácil entendernos por allí.


Y también gracias a Zamorate, lo de vim me viene de lujo, lo uso a diario pero aún me falta mucho por aprender. Lo del file no me ayudaba mucho:

[diego@heine gujisender]$ file agenda.xml
agenda.xml: XML document text



Saludos
(*s_iter) es un string de la STL.


Ok, ese es tu problema, ¿ has probado a utilizar una std::wstring en lugar de una std::string ?

Yo también creo que el problema está en esto o en el código que he pegado en el primer post. Si es necesario te paso todo el código para guardar la agenda, que no llega a 100 lineas.


Ayudaría...

Gracias de nuevo ferdy, te he agregado en jabber, por si crees que es más fácil entendernos por allí.


Como tu prefieras.

Lo del file no me ayudaba mucho:


file -m es lo que debes usar. Sin embargo te puede equivocar si no hay diferencias entre la representación unicode y la ascii del fichero.

- ferdy
6 respuestas