• Publicidad

Crear un fichero XML

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Crear un fichero XML

Notapor fgalves » 2006-12-29 03:46 @199

Hola a todos,

Explorer, muchas gracias por la aclaración en tu mensaje anterior sobre arrays vacíos (modo lista y modo escalar).

Estoy tratando de implementar un script que tome como entrada 2 ficheros XML: uno conteniendo una selección de campos y otro conteniendo la lista de campos disponibles. El caso es que debo generar un XML como resultado conteniendo sólo aquellos campos que han sido seleccionados y disponibles (es decir, la intersección).
Para ello estoy usando el modulo XML::Simple.

El caso es que mi duda es simple: ¿como crear un XML?
Supongo que la operación debe ser realizada a la inversa que un XMLin (XMLout), es decir, crear una estructura HASH con un formato compatible al de un XML y luego convertirlo en fichero.

¿Alguien me puede echar una mano y darme algún ejemplo si es posible?
Otra pregunta mas: ¿alguien sabe cómo imprimir el contenido entero de un hash correspondiente a un XMLin?
¡Muchísimas gracias!
Saludos y buenas fiestas para todos,
Felipe
fgalves
Perlero nuevo
Perlero nuevo
 
Mensajes: 210
Registrado: 2006-09-25 13:54 @621

Publicidad

Notapor explorer » 2006-12-29 21:06 @920

Pues... un ejemplo... en este mismo foro... :-)

Usando la opción Buscar, he puesto XML::Simple y activo la opción de buscar por todas las palabras a la vez.

Un ejemplo que sale:
viewtopic.php?t=1261&highlight=xml+simple

De todas formas, construir con XML::Simple no es tan simple, al principio. Siempre hay que hacer pruebas y usar mucho la ayuda del Data::Dumper.

Casi mejor usar otro módulo XML para construir.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor fgalves » 2007-01-09 04:52 @244

Hola Explorer,

Disculpa mi ultimo mail... Crei haber descifrado en tu codigo de ejemplo un mensaje oculto como el codigo da Vinci... vamos, que te pido disculpas por la tonteria que escribi.

Estoy intentando crear un XML dinamicamente. Dicho XML tiene la pinta siguiente:


Código: Seleccionar todo
<?xml version='1.0'?>

<!DOCTYPE Projection SYSTEM "projection.dtd">
<Projection Type="Projection" ReportName="Example" ProcessName="Example">

<Families>
  <Family Name="...." Major=".." Minor=".." />
  ...
</Families>

<DisplayParams>
...
</DisplayParams>

<ProjFields>
...
</ProjFields>

</Projection>



Estoy empezando por el nodo Families:

Código: Seleccionar todo
my $tempXML;
   
    foreach ( @availableFamilies ) {
        push @{$tempXML->{Families}}, {
            Name   => $_,
            Major  => '1',
            Minor  => '0'
            }
    }
   
    my $exploitableXML = XMLout($tempXML,RootName=> "Projection",NoAttr => 1);       
    print Data::Dumper->Dump($exploitableXML);



Pero al lanzarlo, se queja, dandome el siguiente mensaje de error correspondiente al print Data::Dumper:

Usage: PACKAGE->new(ARRAYREF, [ARRAYREF]) at FqStatsMQRMerge.pl line 337

Alguien me puede echar una mano y mostrarme un ejemplo de como dumpear un XML?
Como crear nodos con parametros como en el XML que quiero crear?

Muchas gracias por cualquier ayuda!!
Felipe
fgalves
Perlero nuevo
Perlero nuevo
 
Mensajes: 210
Registrado: 2006-09-25 13:54 @621

Notapor explorer » 2007-01-09 05:07 @255

Prueba con

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
use Data::Dumper;
#...

#...
print Dumper $exploitableXML;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor fgalves » 2007-01-09 05:27 @268

Gracias por la respuesta Explorer!!!

El caso es que el resultado del dump es el siguiente


Código: Seleccionar todo
$VAR1 = '<Projection>
  <Families>
    <Major>1</Major>
    <Minor>0</Minor>
    <Name>EDI</Name>
  </Families>
  <Families>
    <Major>1</Major>
    <Minor>0</Minor>
    <Name>MDW</Name>
  </Families>
  <Families>
    <Major>1</Major>
    <Minor>0</Minor>
    <Name>EXT</Name>
  </Families>
  <Families>
    <Major>1</Major>
    <Minor>0</Minor>
    <Name>FUNCTIONS</Name>
  </Families>
</Projection>
';


Como expuesto anteriormente, yo quiero obtener el XML de otra forma , es decir, (Name, Major, Minor) como parametros y no como nodos.

Código: Seleccionar todo
<Families>
  <Family Name="...." Major=".." Minor=".." />
  ...
</Families>


Alguien me podria echar una mano con algun ejemplo o algun link util?

Muchas gracias!!!
Felipe
fgalves
Perlero nuevo
Perlero nuevo
 
Mensajes: 210
Registrado: 2006-09-25 13:54 @621

Notapor explorer » 2007-01-09 05:42 @279

Quita la opción 'NoAttr'.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor fgalves » 2007-01-09 07:27 @352

¡¡¡¡Muchas Gracias Explorer!!!!
En efecto, basta con quitarla y los toma como parámetros.

No obstante, tengo todavía ciertas dudas con las que quizás puedas ayudarme:
Hasta ahora he ido creando el XML dinámicamente mediante
el mecanismo que mostraste a otro forero, es decir, haciendo push en una variable temporal a tal efecto ($tempXML):

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
foreach ( @availableFamilies ) {
        push @{$tempXML->{Families}->{Family}}, {
            Name   => $_,
            Major  => '1',
            Minor  => '0'
            }
    }

    #
    # Add the Display Parameters node
    #
    push @{$tempXML->{DisplayParams}->{FlatReportSeparator}}, {Value => ''};
    push @{$tempXML->{DisplayParams}->{NoHeader}}, {};
    push @{$tempXML->{DisplayParams}->{LazyStatDisplay}}, {};
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¿Cómo hago para añadir las siguientes lineas?
Código: Seleccionar todo
<?xml version='1.0'?>

<!DOCTYPE Projection SYSTEM "projection.dtd">


O simplemente:

Código: Seleccionar todo
<NoHeader />


ya que en el caso anterior, me imprime en salida lo siguiente:
Código: Seleccionar todo
<NoHeader></NoHeader>


¡¡Muchas gracias y Saludos!!,
Felipe
fgalves
Perlero nuevo
Perlero nuevo
 
Mensajes: 210
Registrado: 2006-09-25 13:54 @621

Notapor explorer » 2007-01-11 21:00 @916

Para añadir la cabecera <?xml... hay que usar el atributo XMLDecl => 1 o XMLDecl => 'string' en el XMLout().

El <!DOCTYPE... no se puede añadir con este módulo, o, mejor dicho, habría que hacer un filtro SAX que excedería en complejidad a un simple filtro hecho en un segundo paso. Es decir: primero generas el xml con XML::Simple y luego lo vuelves a pasar por un filtro Perl que agrega esa línea.

Y sobre el tema del <NoHeader />, lo mismo. Este módulo es simple (de ahí su nombre), por lo que no podrá hacer muchas cosas especiales.

Tendrás que mirar otros módulos, como el XML::Twig, por ejemplo.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor fgalves » 2007-01-12 04:11 @216

Muchas gracias como siempre Explorer por contestar a mis dudas!!

He probado la opcion XMLDecl => 1 y funciona , pero añade
Código: Seleccionar todo
<?xml version='1.0' standalone='yes'?>



Habria algun modo de generar unicamente lo siguiente?:
Código: Seleccionar todo
<?xml version='1.0' ?>



Mi segunda duda concierne el orden en el que son representados los nodos y los parametros de los nodos. Yo quisiera que se presentaran en el mismo orden en que los he añadido, pero no es el caso.
He probado con la opcion NoSort => 1, pero sigue sin respetar el orden.

En mi caso, vuelco el contenido del hash en un fichero:

Código: Seleccionar todo
my $exploitableXML = XMLout($tempXML,RootName=> "Projection", NoSort => 1, XMLDecl => 1, KeyAttr => [], OutputFile => "$exploitableFileName");


Muchas gracias por cualquier ayuda!
Saludos,
Felipe
fgalves
Perlero nuevo
Perlero nuevo
 
Mensajes: 210
Registrado: 2006-09-25 13:54 @621

Notapor explorer » 2007-01-12 07:07 @338

Si quieres personalizar la cabecera, ya te dije como hacerlo:
Código: Seleccionar todo
XMLDecl => '<?xml version='1.0' ?>'


Y, en cuanto al orden, efectivamente NoSort=>1 dice el manual que sirve para que no ordene alfabéticamente elementos y atributos. El problema es si usamos hashes, cuyo orden de almacenamiento de las claves/valor no es conocido en Perl. Para solventar esto, se suele usar el módulo Tie::IxHash, que permite usar hashes pero manteniendo las claves en el mismo orden en que fueron creadas.

Cuando he tenido que hacer un XML con XML::Simple y me he encontrado con el problema este del orden, la solución fue hacer que los nodos principales tuvieran un orden alfabético. Ejemplo: en una base de datos de días, era importante mantener el orden, por lo que a los nodos se les puso el número de día. Pero... entonces... nos dimos cuenta de que el orden daba igual... El programa que fuese a leer la base de datos en XML sólo tenía que hacer un bucle por todos los días, ordenados numéricamente, sin importar el orden en que estaban escritos dentro del fichero.

Me parece que tendrás que dejar de usar XML::Simple y pasarte a XML::Twig, XML::Generator, XML::TreePP, XML::Writer, o uno de los más completos: XML::Smart.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Siguiente

Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado