Sab Jul 12, 2008 6:13 am
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4143
Ubicación: Valladolid, España
|
|
|
|
|
Cuando XML::Simple lee esas marcas, las convierte a un hash vacío:
| Código: |
$VAR1 = \{
'opr' => '0',
'CodEstadoCivil' => '2',
'CodOficina' => {},
'letra' => 'V',
'FechaCedOrg' => '2005-03-31',
'SNombre' => 'Segundo Nombre',
'cedula' => '123',
'Sexo' => 'M',
'PNombre' => 'nombre',
'FechaNac' => '1980-07-25',
'Naturalizado' => {},
'CodObjecion' => '00',
'PApellido' => 'apellido'
}; |
Lo que se puede hacer es preguntar antes si tenemos un dato o es un hash vacío:
| Perl: | my $CodOficina = 'NULL';
if ( exists $datos-> {CodOficina } ) {
if ( ref($datos-> {CodOficina }) ne 'HASH' ) {
$CodOficina = $datos-> {CodOficina };
}
}
my $Naturalizado = 'NULL';
if ( exists $datos-> {Naturalizado } ) {
if ( ref($datos-> {Naturalizado }) ne 'HASH' ) {
$Naturalizado = $datos-> {Naturalizado };
}
} |
Y ya solo queda pintarlo: | Perl: | print join q{| },
$datos-> {opr } ,
$datos-> {letra } ,
$datos-> {cedula } ,
$datos-> {PNombre } ,
$datos-> {SNombre } ,
$datos-> {PApellido } ,
$datos-> {FechaNac } ,
$datos-> {FechaCedOrg } ,
$datos-> {CodObjecion } ,
$CodOficina ,
$datos-> {CodEstadoCivil } ,
$Naturalizado ,
$datos-> {Sexo };
print "\n"; | Sale:
| Código: |
| 0|V|123|nombre|Segundo Nombre|apellido|1980-07-25|2005-03-31|00|NULL|2|NULL|M |
|
|
|
|

Sab Jul 12, 2008 11:13 am
|
 |
chechoman
Perlero Nuevo

|
Registrado: 02 Jul 2008
Mensajes: 19
|
|
|
|
|
Sí funciono, gracias. Solo me está faltando que el programa en Perl pueda leer valores como 'ñ', 'Ñ' y palabras acentuadas, que algunos nombres incluyen estos datos y vienen en el XML, y Perl al leerlo no los reconoce y cuando empieza a procesar me arroja el error:
| Código: |
| not well-formed (invalid token) at line 1, column 214, byte 214 at /usr/local/lib/perl/5.8.8/XML/Parser.pm line 187 |
Me puse a averiguar y averiguar dándome cabezazos y resulta que es efectivamente porque se necesita una forma para parsear estos caracteres :s.
Instalé entonces en el sistema la librería "expat" y después a través del CPAN instalé la librería XML::Parser, pero no me sirvió de mucho, pensé que quizás debería leer todo el xml y por cada símbolo que consiga lo cambie por un valor "x" y después cuando lo vaya a guardar el valor "x" lo transforme en el que corresponde, pero me pareció algo super enrollado ademas de que me puede saturar el servicio con tantos cálculos que realiza, ya que este programa en Perl está realizando varias cosas como por ejemplo leer muchos .zip y verificar la integridad a través de sha1 y compararla, después descomprimirlos y hacer un respaldo del zip, posteriormente leer los xml y procesarlos y es ahí donde me arroja el error con los caracteres, de verdad no sé qué hacer por ahí :s |
|

Sab Jul 12, 2008 11:49 am
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4143
Ubicación: Valladolid, España
|
|
|
|
|
| Tienes que ver cómo está codificado el carácter que está en la posición de fallo que te indica (línea 1, columna 214). Debe coincidir la codificación con la indicada en la cabecera del xml. |
|
Sab Jul 12, 2008 12:32 pm
|
 |
chechoman
Perlero Nuevo

|
Registrado: 02 Jul 2008
Mensajes: 19
|
|
|
|
|
| No, pues la codificación del xml es utf-8, y como estos son caracteres que no están dentro de esta configuración es que arroja el error. |
|

Sab Jul 12, 2008 1:07 pm
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4143
Ubicación: Valladolid, España
|
|
|
|
|
Precisamente. No es un error lo que te sale en el mensaje. Si la codificación interna de los caracteres no coincide con lo que pone en la cabecera, entonces el xml no está bien formado (not well-formed), y por eso es rechazado.
Deberás decidir qué hacer:
* cambiar la cabecera para que refleje la codificación de esos caracteres
* cambiar la codificación de esos caracteres, en origen (no tú)
* cambiar la codificación de esos caracteres tú mismo.
La más cómoda es la primera: solo tienes que cambiar una línea.
La más idónea es la segunda: no es problema tuyo recibir xml que están mal formados
La más horrible es la tercera: convertirá el proyecto informático en una inmensa chapuza.
P.D. Hablando de acentos, se te escapan algunos, cuando escribes aquí 
Ultima edición por explorer el Dom Jul 13, 2008 5:49 am, editado 1 vez |
|

Sab Jul 12, 2008 11:03 pm
|
 |
chechoman
Perlero Nuevo

|
Registrado: 02 Jul 2008
Mensajes: 19
|
|
|
|
|
Es correcto, lo que dices es cierto, pero la realidad es que los xml van a llegar siempre con este esquema (mal formado en este caso), la verdad es que el origen debería entregarme cada xml con los datos correctos, es decir en caso de una 'ñ' que tenga 'ñ' pero eso no va a suceder, entonces lo que he pensado hacer es leer cada XML y que me busque los caracteres especiales, es decir 'ñ', 'Ñ', 'í', 'ó', 'ú', 'á', 'é', etc. y los reemplace por el código correspondiente, es decir la 'ñ' por 'ñ', pero no me funciona , busqué también si es algo sobre el utf8 y por eso coloqué la línea "use utf8;" pero tampoco funcionó, solo lo único que quiero es que al leer cada XML verifique si consigue alguno de estos caracteres y los sustituya por los caracteres que sí puede leer, o sea, si consigue una 'ñ' la cambie por 'ñ' en el archivo XML. |
|

Dom Jul 13, 2008 9:28 am
|
 |
chechoman
Perlero Nuevo

|
Registrado: 02 Jul 2008
Mensajes: 19
|
|
|
|
|
| Estuve haciendo otras pruebas directamente en el XML, y resulta que si cambio en la primera etiqueta "<?xml ..... " el valor que dice encoding="utf-8" por el de "iso-8859-1" cuando ejecuto el programa en Perl lo hace perfectamente, con eso me doy cuenta que el problema se resuelve al cambiar este valor, el asunto es que no logro hacerlo de forma automática, es decir sin tener que yo abrir el archivo XML y cambiarle este valor, ¿habrá alguna forma de que mi programa abra el XML , le cambie este valor, lo cierre y de ahí siga el proceso de lectura?. |
|
Dom Jul 13, 2008 11:18 am
|
 |
Jenda
Perlero Frecuente

|
Registrado: 29 Oct 2007
Mensajes: 106
Ubicación: Praga, Republica Checa
|
|
|
|

Dom Jul 13, 2008 11:34 am
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4143
Ubicación: Valladolid, España
|
|
|
|
|
Esa es la peor solución. Se llama 'codificar en entidades' (busca por 'entities' en estos foros).
Primero: aún no nos has dicho en qué están codificados esos caracteres. Hemos supuesto que si es un XML y en la cabecera pone algo como encoding="UTF-8" entonces el contenido debería estar codificado de esa manera. Si está en otra, estás en problemas.
Segundo: Perl, por defecto, piensa que siempre estás trabajando con la codificación iso-8859-1, que es la más normal, con los caracteres anglosajones y centroeuropeos. En Español usamos el iso-8859-15, porque además de los acentos incluye el signo del euro. Cuando necesitamos que Perl gestione ficheros, entradas y/o salidas en que la codificación de unos es distinta de la codificación de salida, tenemos que indicarle a Perl cuáles son esas codificaciones. El uso de 'use utf8;' dentro de un programa solo sirve para decirle a Perl que ese mismo programa contiene algunos caracteres escritos en esa codificación. No sirve para decirle que vamos a leer o escribir en esa codificación. Es solo para los caracteres escritos en el propio programa.
Aquí tienes un ejemplo de trabajo con caracteres escritos en otra codificación.
Tenemos el siguiente fichero xml:
| XML: | <?xml version="1.0" encoding="UTF-8"?>
<datos opr="0">
<letra>VñÑáéíóúÁÉÍÓÚ</letra>
<cedula>123</cedula>
<PNombre>nombre</PNombre>
<SNombre>Segundo Nombre</SNombre>
<PApellido>apellido</PApellido>
<FechaNac>1980-07-25</FechaNac>
<FechaCedOrg>2005-03-31</FechaCedOrg>
<CodObjecion>00</CodObjecion>
<CodOficina>Office</CodOficina>
<CodEstadoCivil>2</CodEstadoCivil>
<Naturalizado></Naturalizado>
<Sexo>M</Sexo>
</datos> |
Fíjate que en la entrada '<letra>' he incluido un montón de caracteres 'extraños'. Esto lo he hecho con un editor de textos que escribe en codificación utf8 y, además, mi terminal de trabajo también está en utf8. Para comprobar que está bien escrito en utf8, lo volcamos a nivel de byte:
| Código: |
explorer@casa:~/Documents/Desarrollo> hexdump -C kk.xml
00000000 3c 3f 78 6d 6c 20 76 65 72 73 69 6f 6e 3d 22 31 |<?xml version="1|
00000010 2e 30 22 20 65 6e 63 6f 64 69 6e 67 3d 22 55 54 |.0" encoding="UT|
00000020 46 2d 38 22 3f 3e 0a 3c 64 61 74 6f 73 20 6f 70 |F-8"?>.<datos op|
00000030 72 3d 22 30 22 3e 0a 20 20 20 20 20 20 20 20 3c |r="0">. <|
00000040 6c 65 74 72 61 3e 56 c3 b1 c3 91 c3 a1 c3 a9 c3 |letra>V.........|
00000050 ad c3 b3 c3 ba c3 81 c3 89 c3 8d c3 93 c3 9a 3c |...............<|
00000060 2f 6c 65 74 72 61 3e 0a 20 20 20 20 20 20 20 20 |/letra>. |
00000070 3c 63 65 64 75 6c 61 3e 31 32 33 3c 2f 63 65 64 |<cedula>123</ced|
00000080 75 6c 61 3e 0a 20 20 20 20 20 20 20 20 3c 50 4e |ula>. <PN|
00000090 6f 6d 62 72 65 3e 6e 6f 6d 62 72 65 3c 2f 50 4e |ombre>nombre</PN|
000000a0 6f 6d 62 72 65 3e 0a 20 20 20 20 20 20 20 20 3c |ombre>. <|
000000b0 53 4e 6f 6d 62 72 65 3e 53 65 67 75 6e 64 6f 20 |SNombre>Segundo |
000000c0 4e 6f 6d 62 72 65 3c 2f 53 4e 6f 6d 62 72 65 3e |Nombre</SNombre>|
000000d0 0a 20 20 20 20 20 20 20 20 3c 50 41 70 65 6c 6c |. <PApell|
000000e0 69 64 6f 3e 61 70 65 6c 6c 69 64 6f 3c 2f 50 41 |ido>apellido</PA|
000000f0 70 65 6c 6c 69 64 6f 3e 0a 20 20 20 20 20 20 20 |pellido>. |
00000100 20 3c 46 65 63 68 61 4e 61 63 3e 31 39 38 30 2d | <FechaNac>1980-|
00000110 30 37 2d 32 35 3c 2f 46 65 63 68 61 4e 61 63 3e |07-25</FechaNac>|
00000120 0a 20 20 20 20 20 20 20 20 3c 46 65 63 68 61 43 |. <FechaC|
00000130 65 64 4f 72 67 3e 32 30 30 35 2d 30 33 2d 33 31 |edOrg>2005-03-31|
00000140 3c 2f 46 65 63 68 61 43 65 64 4f 72 67 3e 0a 20 |</FechaCedOrg>. |
00000150 20 20 20 20 20 20 20 3c 43 6f 64 4f 62 6a 65 63 | <CodObjec|
00000160 69 6f 6e 3e 30 30 3c 2f 43 6f 64 4f 62 6a 65 63 |ion>00</CodObjec|
00000170 69 6f 6e 3e 0a 20 20 20 20 20 20 20 20 3c 43 6f |ion>. <Co|
00000180 64 4f 66 69 63 69 6e 61 3e 4f 66 66 69 63 65 3c |dOficina>Office<|
00000190 2f 43 6f 64 4f 66 69 63 69 6e 61 3e 0a 20 20 20 |/CodOficina>. |
000001a0 20 20 20 20 20 3c 43 6f 64 45 73 74 61 64 6f 43 | <CodEstadoC|
000001b0 69 76 69 6c 3e 32 3c 2f 43 6f 64 45 73 74 61 64 |ivil>2</CodEstad|
000001c0 6f 43 69 76 69 6c 3e 0a 20 20 20 20 20 20 20 20 |oCivil>. |
000001d0 3c 4e 61 74 75 72 61 6c 69 7a 61 64 6f 3e 3c 2f |<Naturalizado></|
000001e0 4e 61 74 75 72 61 6c 69 7a 61 64 6f 3e 0a 20 20 |Naturalizado>. |
000001f0 20 20 20 20 20 20 3c 53 65 78 6f 3e 4d 3c 2f 53 | <Sexo>M</S|
00000200 65 78 6f 3e 0a 3c 2f 64 61 74 6f 73 3e 0a |exo>.</datos>.|
0000020e |
Vemos que los caracteres extraños están codificados así:
| Código: |
| c3 b1 c3 91 c3 a1 c3 a9 c3 ad c3 b3 c3 ba c3 81 c3 89 c3 8d c3 93 c3 9a |
que, efectivamente, indica que los caracteres están codificados en utf8 (ocupan dos bytes, en lugar de uno solo, si estuvieran codificados en iso-8859-1 o iso-8859-15).
Ahora, tenemos el siguiente programa:
| Perl: | #!/usr/bin/perl
use XML:: Simple;
use Data:: Dumper;
my $datos = XMLin ('kk.xml');
print Dumper \ $datos;
my $CodOficina = 'NULL';
if ( exists $datos-> {CodOficina } ) {
if ( ref($datos-> {CodOficina }) ne 'HASH' ) {
$CodOficina = $datos-> {CodOficina };
}
}
my $Naturalizado = 'NULL';
if ( exists $datos-> {Naturalizado } ) {
if ( ref($datos-> {Naturalizado }) ne 'HASH' ) {
$Naturalizado = $datos-> {Naturalizado };
}
}
#binmode(STDOUT, ':utf8');
print join q{| },
$datos-> {opr } ,
$datos-> {letra } ,
$datos-> {cedula } ,
$datos-> {PNombre } ,
$datos-> {SNombre } ,
$datos-> {PApellido } ,
$datos-> {FechaNac } ,
$datos-> {FechaCedOrg } ,
$datos-> {CodObjecion } ,
$CodOficina ,
$datos-> {CodEstadoCivil } ,
$Naturalizado ,
$datos-> {Sexo };
print "\n"; | Es el mismo programa tuyo de antes, pero le he añadido una línea, comentada:
| Perl: | #binmode(STDOUT, ':utf8');
| luego explico porqué.
Si lo ejecutamos, la salida es:
| Código: |
explorer@casa:~/Documents/Desarrollo> ./kk.pl
$VAR1 = \{
'opr' => '0',
'CodEstadoCivil' => '2',
'CodOficina' => 'Office',
'letra' => "V\x{f1}\x{d1}\x{e1}\x{e9}\x{ed}\x{f3}\x{fa}\x{c1}\x{c9}\x{cd}\x{d3}\x{da}",
'FechaCedOrg' => '2005-03-31',
'SNombre' => 'Segundo Nombre',
'cedula' => '123',
'Sexo' => 'M',
'PNombre' => 'nombre',
'FechaNac' => '1980-07-25',
'Naturalizado' => {},
'CodObjecion' => '00',
'PApellido' => 'apellido'
};
0|V������������|123|nombre|Segundo Nombre|apellido|1980-07-25|2005-03-31|00|Office|2|NULL|M |
Vemos lo siguiente:
* fijándonos en la línea de la marca '<letra>', vemos que Perl, con el módulo XML::Simple, ha leído correctamente el fichero: estaba en utf8 y ha transformado los caracteres extraños en codificación iso-8859-1:
| Código: |
\x{f1}\x{d1}\x{e1}\x{e9}\x{ed}\x{f3}\x{fa}\x{c1}\x{c9}\x{cd}\x{d3}\x{da}
ñ Ñ á é í ó ú Á É Í Ó Ú |
* pero, a la hora de hacer el print, vemos que salen caracteres mucho más extraños.
Eso es debido a que mi terminal está trabajando en la codificación utf8, y Perl me está mandando caracteres que están en iso-8859-1. Si cambio la codificación de mi terminal a iso-8859-1, la salida es correcta:
| Código: |
| 0|VñÑáéíóúÁÉÍÓÚ|123|nombre|Segundo Nombre|apellido|1980-07-25|2005-03-31|00|Office|2|NULL|M |
Bien, entonces el problema está en que queremos que los caracteres que saquemos hacia el exterior (sea la salida estándar o un fichero, queremos que lo haga en la misma codificación que la entrada: utf8.
Nos basta indicar a Perl que en las operaciones de ficheros, aplique un cambio de codificación.
Si descomentamos la línea anterior:
le estamos diciendo que la salida estándar (STDOUT, el que usa por defecto el print) queremos que sea en codificación 'utf8'. Perl hará los cambios de los caracteres y nos sacará el resultado deseado:
| Código: |
explorer@casa:~/Documents/Desarrollo> ./kk.pl
$VAR1 = \{
'opr' => '0',
'CodEstadoCivil' => '2',
'CodOficina' => 'Office',
'letra' => "V\x{f1}\x{d1}\x{e1}\x{e9}\x{ed}\x{f3}\x{fa}\x{c1}\x{c9}\x{cd}\x{d3}\x{da}",
'FechaCedOrg' => '2005-03-31',
'SNombre' => 'Segundo Nombre',
'cedula' => '123',
'Sexo' => 'M',
'PNombre' => 'nombre',
'FechaNac' => '1980-07-25',
'Naturalizado' => {},
'CodObjecion' => '00',
'PApellido' => 'apellido'
};
0|VñÑáéíóúÁÉÍÓÚ|123|nombre|Segundo Nombre|apellido|1980-07-25|2005-03-31|00|Office|2|NULL|M |
Para comprobar que, efectivamente, están en utf8, hacemos lo de antes, un volcado a nivel de byte:
explorer@casa:~/Documents/Desarrollo> ./kk.pl|hexdump -C
| Código: |
00000000 24 56 41 52 31 20 3d 20 5c 7b 0a 20 20 20 20 20 |$VAR1 = \{. |
00000010 20 20 20 20 20 20 20 27 6f 70 72 27 20 3d 3e 20 | 'opr' => |
00000020 27 30 27 2c 0a 20 20 20 20 20 20 20 20 20 20 20 |'0',. |
00000030 20 27 43 6f 64 45 73 74 61 64 6f 43 69 76 69 6c | 'CodEstadoCivil|
00000040 27 20 3d 3e 20 27 32 27 2c 0a 20 20 20 20 20 20 |' => '2',. |
00000050 20 20 20 20 20 20 27 43 6f 64 4f 66 69 63 69 6e | 'CodOficin|
00000060 61 27 20 3d 3e 20 27 4f 66 66 69 63 65 27 2c 0a |a' => 'Office',.|
00000070 20 20 20 20 20 20 20 20 20 20 20 20 27 6c 65 74 | 'let|
00000080 72 61 27 20 3d 3e 20 22 56 5c 78 7b 66 31 7d 5c |ra' => "V\x{f1}\|
00000090 78 7b 64 31 7d 5c 78 7b 65 31 7d 5c 78 7b 65 39 |x{d1}\x{e1}\x{e9|
000000a0 7d 5c 78 7b 65 64 7d 5c 78 7b 66 33 7d 5c 78 7b |}\x{ed}\x{f3}\x{|
000000b0 66 61 7d 5c 78 7b 63 31 7d 5c 78 7b 63 39 7d 5c |fa}\x{c1}\x{c9}\|
000000c0 78 7b 63 64 7d 5c 78 7b 64 33 7d 5c 78 7b 64 61 |x{cd}\x{d3}\x{da|
000000d0 7d 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 |}",. |
000000e0 27 46 65 63 68 61 43 65 64 4f 72 67 27 20 3d 3e |'FechaCedOrg' =>|
000000f0 20 27 32 30 30 35 2d 30 33 2d 33 31 27 2c 0a 20 | '2005-03-31',. |
00000100 20 20 20 20 20 20 20 20 20 20 20 27 53 4e 6f 6d | 'SNom|
00000110 62 72 65 27 20 3d 3e 20 27 53 65 67 75 6e 64 6f |bre' => 'Segundo|
00000120 20 4e 6f 6d 62 72 65 27 2c 0a 20 20 20 20 20 20 | Nombre',. |
00000130 20 20 20 20 20 20 27 63 65 64 75 6c 61 27 20 3d | 'cedula' =|
00000140 3e 20 27 31 32 33 27 2c 0a 20 20 20 20 20 20 20 |> '123',. |
00000150 20 20 20 20 20 27 53 65 78 6f 27 20 3d 3e 20 27 | 'Sexo' => '|
00000160 4d 27 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 |M',. |
00000170 27 50 4e 6f 6d 62 72 65 27 20 3d 3e 20 27 6e 6f |'PNombre' => 'no|
00000180 6d 62 72 65 27 2c 0a 20 20 20 20 20 20 20 20 20 |mbre',. |
00000190 20 20 20 27 46 65 63 68 61 4e 61 63 27 20 3d 3e | 'FechaNac' =>|
000001a0 20 27 31 39 38 30 2d 30 37 2d 32 35 27 2c 0a 20 | '1980-07-25',. |
000001b0 20 20 20 20 20 20 20 20 20 20 20 27 4e 61 74 75 | 'Natu|
000001c0 72 61 6c 69 7a 61 64 6f 27 20 3d 3e 20 7b 7d 2c |ralizado' => {},|
000001d0 0a 20 20 20 20 20 20 20 20 20 20 20 20 27 43 6f |. 'Co|
000001e0 64 4f 62 6a 65 63 69 6f 6e 27 20 3d 3e 20 27 30 |dObjecion' => '0|
000001f0 30 27 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 |0',. |
00000200 27 50 41 70 65 6c 6c 69 64 6f 27 20 3d 3e 20 27 |'PApellido' => '|
00000210 61 70 65 6c 6c 69 64 6f 27 0a 20 20 20 20 20 20 |apellido'. |
00000220 20 20 20 20 7d 3b 0a 30 7c 56 c3 b1 c3 91 c3 a1 | };.0|V......|
00000230 c3 a9 c3 ad c3 b3 c3 ba c3 81 c3 89 c3 8d c3 93 |................|
00000240 c3 9a 7c 31 32 33 7c 6e 6f 6d 62 72 65 7c 53 65 |..|123|nombre|Se|
00000250 67 75 6e 64 6f 20 4e 6f 6d 62 72 65 7c 61 70 65 |gundo Nombre|ape|
00000260 6c 6c 69 64 6f 7c 31 39 38 30 2d 30 37 2d 32 35 |llido|1980-07-25|
00000270 7c 32 30 30 35 2d 30 33 2d 33 31 7c 30 30 7c 4f ||2005-03-31|00|O|
00000280 66 66 69 63 65 7c 32 7c 4e 55 4c 4c 7c 4d 0a |ffice|2|NULL|M.|
0000028f |
Lo interesante está al final. Vemos que en el offset 0x22A empieza la secuencia de bytes de los caracteres acentuados, dos bytes cada uno, en codificación 'utf8'.
Pero entonces... ¿por qué hay tanto lío? Es decir, ¿por qué el módulo XML::Simple trabaja de esta manera, leyendo 'utf8' y pasándolo a iso-8859-1? ¿y por qué tenemos que indicar a mano la codificación de salida? En parte, la respuesta es por la forma de trabajo tradicional de Perl: siempre piensa que estamos en iso-8859-1 (algo que ya se ha cambiado desde la versión 5.8 en adelante). Y el por qué tenemos que hacer el cambio de codificación en la salida de datos es porque XML::Simple no contempla ese trabajo con el xml... es decir... si leemos el manual del módulo, habla de leer, modificar y de escribir el xml. Pero no habla nada de pintar los valores, de forma independiente. Hay un problema mayor: XML::Simple no maneja la codificación de los caracteres. Esa labor la hacen los módulos que hacen el 'parseado' del fichero (XML::Parser o SAX) Según sea uno u otro, el comportamiento es distinto. Y también distinto si tu versión de Perl es inferior a la 5.8.8. A la hora de sacar el fichero fuera, saldrá según la codificación indicada para el manipulador del fichero indicado.
Hay varias soluciones.
1.- Hacer que Perl trabaje siempre en 'utf8' en las operaciones de entrada y salida. Una forma de hacerlo es poniendo la opción '-CS' para el intérprete perl. En la primera línea, ponemos | Perl: | #!/usr/bin/perl -CS
| y todas las salidas serán con codificación 'utf8'. Más información en perlrun.
2.- Usar binmode() u open() con una codificación para indicar qué codificación usar. Ejemplo de binmode(), la línea comentada de arriba. Ejemplo de open:
| Perl: | open my $fh, '>:encoding(utf8)', $fichero or die "$!\n";
XMLout ($ref, OutputFile => $fh); |
Hay más opciones, como usar el pragma 'open', pero lo más recomendable es usar la segunda propuesta: indicar la codificación en el momento del open().
Hilo del mismo tema en otro foro: http://coding.derkeiler.com/Archive/Perl/comp.lang.perl.misc/2006-03/threads.html#01574
Ultima edición por explorer el Lun Sep 01, 2008 4:06 pm, editado 1 vez |
|

Dom Jul 13, 2008 11:42 am
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4143
Ubicación: Valladolid, España
|
|
|
|
|
| chechoman escribió: | | Estuve haciendo otras pruebas directamente en el XML, y resulta que si cambio en la primera etiqueta "<?xml ..... " el valor que dice encoding="utf-8" por el de "iso-8859-1" cuando ejecuto el programa en Perl lo hace perfectamente |
Ya tenemos una pista. Es posible que el fichero esté codificado en iso-8859-1.
Si es así, puedes leer el fichero de esta manera:
| Perl: | open my $fh, '<:encoding(iso-8859-1)', 'kk.xml' or die "$!\n";
my $datos = XMLin ($fh); |
|
|

Lun Jul 14, 2008 1:43 pm
|
 |
chechoman
Perlero Nuevo

|
Registrado: 02 Jul 2008
Mensajes: 19
|
|
|
|
|
Bueno, explorer, ante todo muchas gracias por toda tu ayuda, y también por toda la ayuda de las demás personas que han participado en este tema.
Resulta que el problema es que los XML me vienen con una codificación que me causaba problemas (UTF-8) así que lo que tenía que hacer era leer el xml, buscar este texto y colocarle iso-8859-1 la cual es la codificación que me sirve. Al principio lo hice con un comando de Linux: sed, pero el problema era que se tardaba mucho en la ejecución, es decir, por unos 40 mil archivos tardaba alrededor de 20 minutos, así que escribí unas líneas para que hiciera todo dentro del mismo Perl ¡y la ejecución bajo a unos 7 minutos! Aquí agrego entonces el código para permitir leer las 'ñ' y los acentos en un XML: | Perl: | my $filename= "/home/principal/lector/xml/$a";
my $oldtext= "UTF-8";
my $newtext= "iso-8859-1";
open (IN, "$filename") || die $!;
## imprimo el contenido moficado en el archivo .bak
open (OUT, ">$filename.bak") || die $!;
while ($_ = <IN> ) {
## Si existe el texto lo reemplazo
if ($_ =~ / $oldtext/i ) {
$_ =~ s/ $oldtext/ $newtext/gi;
}
print OUT "$_";
}
close (OUT );
close (IN );
# if ($filename =~ /\.wiki|\.awiki/)
## copio el contenido del archivo moficado .bak al archivo original
rename("$filename.bak", "$filename") || die $!; |
|
|

Lun Jul 14, 2008 4:43 pm
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4143
Ubicación: Valladolid, España
|
|
|
|
|
Dos puntualizaciones.
La primera, decirte que si los XML están en una codificación distinta de la indicada en la cabecera, entonces la culpa no es tuya, sino del origen. Que lo despidan
La segunda, que no necesitas hacer nada de lo que indicas si abres el xml como te indicaba un poco más arriba, con el open().
De todas formas, enhorabuena por encontrar la solución. |
|
Powered by phpBB © 2001, 2005 phpBB Group
|