Perl en Español

  1. Home
  2. Tutoriales
  3. Foro
  4. Artículos
  5. Donativos
  6. Publicidad
 

XML básico. Por dónde comenzar

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Básico
Mensaje Jue Jun 26, 2008 4:37 pm
Rene Serrano
Perlero Nuevo
Perlero Nuevo
Registrado: 27 Nov 2006
Mensajes: 82
Ubicación: El salvador CA
XML básico. Por dónde comenzar Responder citando

Buen día, compañero

Estoy tratando de hacer unos archivos XML con la siguiente estructura pero estuve leyendo un par de módulos en CPAN para crear pero no sé cuál usar, y no sé por dónde comenzar. Alguna idea...

*var variable yo lo llamo desde una BD

Si me echan una mano con un ejemplo más o menos así.

Se los agradecería.

Saludos

XML:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<eConnect>
<RMCustomerMasterType>
<eConnectProcessInfo>
        <ConnectionString>
                conexxion
        </ConnectionString>
</eConnectProcessInfo>
<taUpdateCreateCustomerRcd>
        <CUSTNMBR>000000239</CUSTNMBR>
        <HOLD>0</HOLD>
        <INACTIVE>0</INACTIVE>
        <CUSTNAME>var</CUSTNAME>
        <SHRTNAME>var</SHRTNAME>
        <STMTNAME>var</STMTNAME>
        <CUSTCLAS>CREDITO</CUSTCLAS>
        <CUSTPRIORITY>1</CUSTPRIORITY>
        <ADRSCODE>PRINCIPAL</ADRSCODE>
        <CNTCPRSN>var</CNTCPRSN>
        <ADDRESS1>var
</ADDRESS1>
        <ADDRESS2></ADDRESS2>
        <ADDRESS3></ADDRESS3>
        <CITY></CITY>
        <STATE></STATE>
        <ZIPCODE>00001</ZIPCODE>
        <CCode>var</CCode>
        <COUNTRY>var</COUNTRY>
        <PHNUMBR1>var</PHNUMBR1>
        <PHNUMBR2/>
        <PHNUMBR3/>
        <FAX></FAX>
        <CRLMTTYP>0</CRLMTTYP>
        <UseCustomerClass>1</UseCustomerClass>
        <SLPRSNID>var</SLPRSNID>
        <SALSTERR>var</SALSTERR>
        <TXRGNNUM>var</TXRGNNUM>
        <COMMENT1/>
</taUpdateCreateCustomerRcd>
</RMCustomerMasterType>
Mensaje Jue Jun 26, 2008 4:42 pm
kidd
Creador de Perl en Español
Creador de Perl en Español
Registrado: 15 Oct 2003
Mensajes: 1389
Ubicación: México
Responder citando

Hola,

En Perl tienes una gran variedad de módulos para manipular XML. Te recomiendo que entres al siguiente artículo que te dá un vistazo a la mayoría de estos módulos:
http://www.xml.com/pub/a/2000/04/05/feature/index.html

De ahí quizá puedas ya tomar una decisión sobre qué módulo te acomoda más.

Saludos
Mensaje Jue Jun 26, 2008 7:08 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4143
Ubicación: Valladolid, España
Responder citando

Yo te recomiendo XML::Smart. Tienes también un Tutorial y preguntas frecuentes.

Perl:
#!/usr/bin/perl
use XML::Smart;
use strict;
use warnings;

my $xml = XML::Smart->new();

my $contenido_del_xml = {
    eConnectProcessInfo => {
        ConnectionString => "\n\t\tconexxion\n",
    },
    taUpdateCreateCustomerRcd => {
        CUSTNMBR => '000000239',
        HOLD     => 0,
        INACTIVE => 0,
        CUSTNAME => 'var',
        SHRTNAME => 'var',
        STMTNAME => 'var',
        CUSTCLAS => 'CREDITO',
        CUSTPRIORITY => 1,
        ADRSCODE => 'PRINCIPAL',
        CNTCPRSN => 'var',
        ADDRESS1 => "var\n",
        ADDRESS2 => '',
        ADDRESS3 => '',
        CITY     => '',
        STATE    => '',
        ZIPCODE  => '00001',
        CCode    => 'var',
        COUNTRY  => 'var',
        PHNUMBR1 => 'var',
        PHNUMBR2 => '',
        PHNUMBR3 => '',
        FAX      => '',
        CRLMTTYP => 0,
        UseCustomerClass => 1,
        SLPRSNID => 'var',
        SALSTERR => 'var',
        TXRGNNUM => 'var',
        COMMENT1 => '',
    },
};

$xml->{RMCustomerMasterType} = $contenido_del_xml;

# Obligamos a que las claves dentro de taUpdateCreateCustomerRcd sean nodos, no atributos
foreach ( keys %{$contenido_del_xml->{taUpdateCreateCustomerRcd}} ) {
    $xml->{RMCustomerMasterType}->{taUpdateCreateCustomerRcd}->{$_}->set_node(1);
}

my $xmldata = $xml->data(nometagen=>1);
print $xmldata;

XML:
<?xml version="1.0" encoding="iso-8859-1" ?>
<RMCustomerMasterType>
  <eConnectProcessInfo>
  <ConnectionString>
                conexxion
</ConnectionString>
  </eConnectProcessInfo>
  <taUpdateCreateCustomerRcd>
    <ADDRESS1>var
</ADDRESS1>
    <ADRSCODE>PRINCIPAL</ADRSCODE>
    <CCode>var</CCode>
    <CNTCPRSN>var</CNTCPRSN>
    <COUNTRY>var</COUNTRY>
    <CRLMTTYP>0</CRLMTTYP>
    <CUSTCLAS>CREDITO</CUSTCLAS>
    <CUSTNAME>var</CUSTNAME>
    <CUSTNMBR>000000239</CUSTNMBR>
    <CUSTPRIORITY>1</CUSTPRIORITY>
    <HOLD>0</HOLD>
    <INACTIVE>0</INACTIVE>
    <PHNUMBR1>var</PHNUMBR1>
    <SALSTERR>var</SALSTERR>
    <SHRTNAME>var</SHRTNAME>
    <SLPRSNID>var</SLPRSNID>
    <STMTNAME>var</STMTNAME>
    <TXRGNNUM>var</TXRGNNUM>
    <UseCustomerClass>1</UseCustomerClass>
    <ZIPCODE>00001</ZIPCODE>
  </taUpdateCreateCustomerRcd>
</RMCustomerMasterType>
Mensaje Vie Jun 27, 2008 11:10 am
Rene Serrano
Perlero Nuevo
Perlero Nuevo
Registrado: 27 Nov 2006
Mensajes: 82
Ubicación: El salvador CA
Responder citando

Gracias Explorer y Kidd,

Estoy viendo que al momento de generar el XML la parte que forzamos a ser nodo me la ordena alfabéticamente y no respeta el orden que le estamos asignando. ¿Qué podrá ser? Y otra: quiero agregar una etiqueta al principio del XML que se llame <eConnect> pero si se la agrego me duplica algunos tag. Este tag es el que abre y cierra el xml o sea el principio y el fin. Una cosa más: cómo puedo modificar esta parte:
HTML:
<?xml version="1.0" encoding="iso-8859-1" ?>


La quiero poner de esta otra forma
HTML:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>

probé con esta forma que encontré pero no me funcionó
Perl:
my $meta = {
    build_from => "version="1.0" encoding="UTF-8""  ,
    } ;
Mensaje Vie Jun 27, 2008 12:37 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4143
Ubicación: Valladolid, España
Responder citando

El que no te la ordene alfabéticamente es porque estamos usando un hash para guardar la estructura. De todas formas, yo creo que da igual cómo queden grabadas esas marcas.

La etiqueta que quieres poner, si es la raíz de todo el XML, deberías entonces cambiar la línea a
Perl:
$xml->{eConnect} = $contenido_del_xml;


Y para modificar la cabecera (que yo creo que no hace falta), edita el fichero XML/Smart/Data.pm. Busca la línea
Perl:
my $xml = qq`<?xml version="1.0" encoding="$enc"$length ?>` ;

y la modificas a tu gusto.
Mensaje Vie Jun 27, 2008 1:01 pm
Rene Serrano
Perlero Nuevo
Perlero Nuevo
Registrado: 27 Nov 2006
Mensajes: 82
Ubicación: El salvador CA
Responder citando

Hola Explorer. Gracias por ayudarme. En este caso sí es necesario el orden esto porque el programa que lo lee lo hace en forma secuencial, verifica primero si el orden de los tag es correcto, si no, lanza una excepción de error (Micro$oft).

Seguiré tus consejos y buscaré la forma de que respete el orden.

Saludos
Mensaje Dom Jun 29, 2008 1:47 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4143
Ubicación: Valladolid, España
Responder citando

Vamos a ver... una explicación antes...

Sí que está contemplado el caso, en el estándar XML, que los contenidos estén en un determinado orden, pero la GRAN mayoría de las aplicaciones modernas ya no lo tienen en cuenta porque acceden al contenido del XML como si fuera un registro devuelto de una base de datos. No importa entonces el orden de los campos leídos porque la aplicación que los lee CONOCE de antemano QUÉ campos existen. Solo se preocupa de saber que hay una librería o módulo que se encarga de leer el XML. Y que esa librería le devolverá los valores de los campos en el orden en que ella se lo pida.

Los casos en los que interesa un determinado orden es, por ejemplo, en los casos en los que la aplicación NO sabe qué campos o contenidos contiene, a priori, el XML. Y, además, el orden indica algún tipo de presentación o traspaso de información a otra sistema (exportación) a otro tipo de base de datos, etc. etc.

Bueno, en cuanto al módulo XML::Smart, veo que hay una función que se llama set_order(), al que se le pueden indicar el orden de las claves.
Mensaje Dom Jun 29, 2008 5:31 pm
Rene Serrano
Perlero Nuevo
Perlero Nuevo
Registrado: 27 Nov 2006
Mensajes: 82
Ubicación: El salvador CA
Responder citando

Bueno, tienes razón, pero en los requerimientos que me hicieron fueron específicos en eso :S, pero bien, resolví utilizando el paquete XML::Generator.

El código me quedó de la siguiente manera:
Perl:
my $gen = XML::Generator->new(':pretty',':encoding');
print $gen->xml(
    eConnect(
        $gen->RMcustemerMasterType(
            $gen->eConnectProcessInfo(
                $gen->eConnectionString("\n\t\ Integrated Security=SSPI")
            ),
            $gen->taUpdateCreateCustomerRcd(
                $gen->CUSTNMBR($row1[0]),
                $gen->HOLD    (0),
                $gen->INACTIVE(0),
                $gen->CUSTNAME($row1[1]),
                $gen->SHRTNAME($row1[1]),
                $gen->STMTNAME($row1[2]),
                $gen->CUSTCLAS('CREDITO'),
                $gen->CUSTPRIORITY(1),
                $gen->ADRSCODE('PRINCIPAL'),
                $gen->CNTCPRSN($row1[3]),
                $gen->ADDRESS1($row1[4]),
                $gen->ADDRESS2(''),
                $gen->ADDRESS3(''),
                $gen->CITY    ($row1[5]),
                $gen->STATE   ($row1[6]),
                $gen->ZIPCODE ('00001'),
                $gen->CCode   (''),
                $gen->COUNTRY (''),
                $gen->PHNUMBR1($row1[7]),
                $gen->PHNUMBR2(''),
                $gen->PHNUMBR3(''),
                $gen->FAX     ($row1[8]),
                $gen->CRLMTTYP(0),
                $gen->UseCustomerClass(1),
                $gen->SLPRSNID($row1[9]),
                $gen->SALSTERR($row1[10]),
                $gen->TXRGNNUM(''),
                $gen->COMMENT1('')
            )
        )
    )
);

El detalle es cuando un campo tiene tilde, me da error, que el carácter no es válido. Eso solo cuando lo abre con IE. Me imagino que tiene que ver con la codificación con la que se crea el XML.

Este lo generé y me da error en el nombre Hugo Crispín.

XML:
<?xml version="1.0" standalone="yes"?>
<eConnect><RMcustemerMasterType>
  <eConnectProcessInfo>
    <eConnectionString>
         Integrated
    </eConnectionString>
  </eConnectProcessInfo>
  <taUpdateCreateCustomerRcd>
    <CUSTNMBR>000000239</CUSTNMBR>
    <HOLD>0</HOLD>
    <INACTIVE>0</INACTIVE>
    <CUSTNAME>Al Macarone Atanasio</CUSTNAME>
    <SHRTNAME>Al Macarone Atanasio</SHRTNAME>
    <STMTNAME>Helados Finos, S.A</STMTNAME>
    <CUSTCLAS>CREITO</CUSTCLAS>
    <CUSTPRIORITY>1</CUSTPRIORITY>
    <ADRSCODE>PRINCIPAL</ADRSCODE>
    <CNTCPRSN>Hugo Crispín</CNTCPRSN>
    <ADDRESS1>13 av.3 Z. 5

    </ADDRESS1>
    <ADDRESS2></ADDRESS2>
    <ADDRESS3></ADDRESS3>
    <CITY></CITY>
    <STATE></STATE>
    <ZIPCODE>00001</ZIPCODE>
    <CCode></CCode>
    <COUNTRY></COUNTRY>
    <PHNUMBR1>23339-6400</PHNUMBR1>
    <PHNUMBR2></PHNUMBR2>
    <PHNUMBR3></PHNUMBR3>
    <FAX></FAX>
    <CRLMTTYP>0</CRLMTTYP>
    <UseCustomerClass>1</UseCustomerClass>
    <SLPRSNID>18</SLPRSNID>
    <SALSTERR>563333331-7</SALSTERR>
    <TXRGNNUM></TXRGNNUM>
    <COMMENT1></COMMENT1>
  </taUpdateCreateCustomerRcd>
</RMcustemerMasterType></eConnect>


¿Me puedes ayudar para ver cómo puedo resolver este problema? Le coloqué esta etiqueta de encoding, pero nada.

Perl:
XML::Generator->new(':pretty',':encoding');


Saludos
Mensaje Dom Jun 29, 2008 5:49 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4143
Ubicación: Valladolid, España
Responder citando

Enhorabuena. Yo tampoco me acordaba de ese módulo (claro, hay dos centenares Smile ).

Sobre el tema de la codificación de caracteres, es algo que se repite mucho últimamente (y que se repetirá mucha más en el futuro). Ya hay varios hilos en este web hablando de este tema.

Resulta que, por defecto, la codificación de XML es utf8. Así que tienes dos opciones: o sacas todos los caracteres en esa codificación o pasas los caracteres especiales a entidades XML.

En tu código Perl, debes configurar el open que graba el fichero XML resultado para que lo grabe en codificación utf8, no iso-8859-1 que es que usa por defecto.

Otra opción: poner en la cabecera del fichero xml que la codificación está en iso-8859-1.
Mensaje Mar Jul 01, 2008 2:22 pm
Rene Serrano
Perlero Nuevo
Perlero Nuevo
Registrado: 27 Nov 2006
Mensajes: 82
Ubicación: El salvador CA
Responder citando

Una consulta: en este módulo, ¿cómo hago para modificar el TAG para la codificación del XML llevarla a este formato?

XML:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
Mensaje Mar Jul 01, 2008 3:10 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4143
Ubicación: Valladolid, España
Responder citando

Función xmldecl().

http://search.cpan.org/~bholzman/XML-Generator-1.01/Generator.pm#xmldecl(@args)
Mensaje Mie Jul 02, 2008 11:22 am
Rene Serrano
Perlero Nuevo
Perlero Nuevo
Registrado: 27 Nov 2006
Mensajes: 82
Ubicación: El salvador CA
Responder citando

Hola, explorer, gracias por tu ayuda, estuve probando este código, sin ninguna variante en el tag. ¿Qué necesito, es correcta esta sintaxis o me falta algo?

Perl:
print $gen->xmldecl({version=>"1.0",encoding=>"UTF-8",standalone=>"no"})


Saludos.

PD. ¡¡¡Gracias por tu invaluable ayuda!!!
Mensaje Mie Jul 02, 2008 3:17 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4143
Ubicación: Valladolid, España
Responder citando

No tengo ni idea, pero según lo indicado en el manual, está esperando una lista de valores, así que será algo así:
Perl:
$gen->xmldecl( version => "1.0", encoding => "UTF-8", standalone => "no" );
Mensaje Mie Jul 02, 2008 3:24 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4143
Ubicación: Valladolid, España
Responder citando

Rene Serrano escribió:
En este caso sí es necesario el orden esto porque el programa que lo lee lo hace en forma secuencial, verifica primero si el orden de los tag es correcto, si no, lanza una excepción de error (Micro$oft).

Entonces, en ese caso, usaría alguno de los módulos que permiten guardar el orden de las claves, como por ejemplo Tie::IxHash.
Perl:
  use Tie::IxHash;
  tie my %attr, 'Tie::IxHash';

  %attr = (name => 'Bob',
           age  => 34,
           job  => 'Accountant',
    'shoe-size' => '12 1/2');
Mensaje Mie Jul 02, 2008 4:51 pm
Rene Serrano
Perlero Nuevo
Perlero Nuevo
Registrado: 27 Nov 2006
Mensajes: 82
Ubicación: El salvador CA
¡¡Solucionado!! Responder citando

Gracias, Explorer si las “llaves” me estaban sobrando y gracias por el tip del modulo Tie

Eres gran ayuda para nosotros lo novatos


Saludos
Publicar nuevo tema   Responder al tema    Foros de discusión -> Básico Todas las horas son GMT - 6 Horas
Página 1 de 1



Powered by phpBB © 2001, 2005 phpBB Group