Foros del Web » Programación para mayores de 30 ;) » Java »

[SOLUCIONADO] Multiples archivos con XSLT & Saxon

Estas en el tema de Multiples archivos con XSLT & Saxon en el foro de Java en Foros del Web. Que tal amigos, soy nuevo en el foro y aquí vengo con un nuevo tema para ustedes, espero puedan apoyarme, como dice el título del ...
  #1 (permalink)  
Antiguo 23/03/2015, 10:59
 
Fecha de Ingreso: marzo-2015
Mensajes: 45
Antigüedad: 9 años, 1 mes
Puntos: 2
Pregunta Multiples archivos con XSLT & Saxon

Que tal amigos, soy nuevo en el foro y aquí vengo con un nuevo tema para ustedes, espero puedan apoyarme, como dice el título del tema, tengo un pequeño inconveniente con las hojas de estilo XSL, soy nuevo con las plantillas y no estoy seguro si estoy realizando las cosas correctamente.

Tengo una carpeta con archivos de texto como se muestra a continuación.

descarga1.txt
descarga2.txt
descarga3.txt
...

Dichos archivos se necesitan convertir a un archivo XML, el cual realizo correctamente con la implementación del código siguiente.

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" />

<xsl:variable name="text" select="tokenize(unparsed-text('file:///C:/Users/Quality/Documents/ProyectoComerciales/download_files/descarga01.txt'),'&#xD;&#xA;')" />

<xsl:template name="main" match="/">
<content>
<items>
<xsl:for-each select="$text">
<xsl:variable name="idi" select="substring(.,1,2)" />
<xsl:if test="$idi = 'OH'">
<item>
<xsl:element name="id"><xsl:value-of select="$idi" /></xsl:element>
<xsl:element name="folio"><xsl:value-of select="substring(.,3,10)" /></xsl:element>
</item>
</xsl:if>
</xsl:for-each>
</items>
<products>
<xsl:for-each select="$text">
<xsl:variable name="idp" select="substring(.,1,2)" />
<xsl:if test="$idp = 'BL'">
<product>
<xsl:element name="id"><xsl:value-of select="$idp" /></xsl:element>
<xsl:element name="code"><xsl:value-of select="substring(.,3,18)" /></xsl:element>
</product>
</xsl:if>
</xsl:for-each>
</products>
<users>
<xsl:for-each select="$text">
<xsl:variable name="idu" select="substring(.,1,2)" />
<xsl:if test="$idu = 'LH'">
<user>
<xsl:element name="id"><xsl:value-of select="$idu" /></xsl:element>
<xsl:element name="num"><xsl:value-of select="substring(.,3,6)" /></xsl:element>
</user>
</xsl:if>
</xsl:for-each>
</users>
</content>
</xsl:template>
</xsl:stylesheet>

Si realizamos la llamada desde Java a este archivo tendremos una conversión exitosa, sin embargo, como podrán ver en la tercera línea del código se puede observar que yo le estoy diciendo que archivo quiero que lea, por lo tanto ahí es donde viene mi problema. Necesito que lea todos los archivos que se encuentran dentro de mi carpeta y valla creando un XML por cada archivo que va leyendo, investigue en Internet que puedo implementar la función collection() que el mismo XSL tiene, por lo que quedaría de la siguiente manera.

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>

<xsl:template name="main" match="/">
<xsl:for-each select="collection('file:///C:/Users/Quality/Documents/ProyectoComerciales/download_files/?select=*.txt')">
<xsl:variable name="file" select="tokenize(document-uri(.),'/')[last()]"/>
<xsl:variable name="text" select="tokenize(unparsed-text($file),'&#xD;&#xA;')"/>
<xsl:for-each select="$text">
<content>
...
</content>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Sin embargo, cuando realizo la ejecución obtengo el siguiente mensaje de error "el contenido no está permitido en el prólogo". La llamada desde Java la realizo mediante el uso del siguiente código Saxon (saxon9he.jar)

try {
Processor proc = new Processor(false);
XsltCompiler comp = proc.newXsltCompiler();
XsltExecutable exp = comp.compile(new StreamSource(new File("C:/Users/Quality/Documents/" +
"ProyectoComerciales/xsl/convertir.xsl")));
Serializer out = new Serializer();
out.setOutputProperty(Serializer.Property.METHOD, "xml");
out.setOutputProperty(Serializer.Property.INDENT, "yes");
out.setOutputFile(new File("C:/Users/Quality/Documents/ProyectoComerciales/xml/descarga.xml"));
XsltTransformer trans = exp.load();
trans.setInitialTemplate(new QName("main"));
trans.setDestination(out);
trans.transform();
} catch (SaxonApiException sae) {
sae.printStackTrace();
}

Serían tan amables de apoyarme con este tema, de antemano, gracias por su tiempo.

P.D. Como le doy formato de código al código (Valga la redundancia) para que no sea vea así, disculpen la molestia, gracias.
  #2 (permalink)  
Antiguo 24/03/2015, 10:36
 
Fecha de Ingreso: marzo-2015
Mensajes: 45
Antigüedad: 9 años, 1 mes
Puntos: 2
Respuesta: Multiples archivos con XSLT & Saxon

Como estan, amigos!

Bueno, simplemente para cerrar el tema, ya que encontré como obtener lo que quería, ahora solo es cuestión de manipular esa colección de archivos de texto, sin mas que comentar gracias por su tiempo.

P.D. Si están interesados en saber como lo resolví, contáctenme y con gusto brindo el código.
  #3 (permalink)  
Antiguo 24/03/2015, 10:48
Avatar de Xerelo  
Fecha de Ingreso: mayo-2009
Mensajes: 2.175
Antigüedad: 15 años
Puntos: 306
Respuesta: Multiples archivos con XSLT & Saxon

¿Y no sería mejor que directamente lo compartas?

Lo que has descubierto puede servir a otra persona sin depender de que tú te conectes o no.
__________________
Cada vez que solucionas los problemas de alguien que no se esfuerza, piensa en que el día de mañana puede llegar a ser tu compañero de trabajo, o peor, tu jefe.
  #4 (permalink)  
Antiguo 24/03/2015, 12:52
 
Fecha de Ingreso: marzo-2015
Mensajes: 45
Antigüedad: 9 años, 1 mes
Puntos: 2
Respuesta: Multiples archivos con XSLT & Saxon

Buen punto. Disculpen, mi cabeza no pensó en ese momento (Tanto investigar, probar, leer, afecta un poco, además me emocione porque finalmente obtuve la salida que quería xD)

Explico... Como bien saben, la función collection() devuelve un lista de los archivos que se encuentran en un directorio en especifico, sin embargo, es IMPORTANTE mencionar que si respetamos la sintaxis de dicha función tal cual lo encontramos en cualquier documentación y/o tutorial de Internet.

collection('file:///C:/Users/Quality/Documents/ProyectoComerciales/download_files/?select=*.txt')

Obtendremos el error siguiente El contenido no está permitido en el prólogo debido a que dicha función interpreta por "defecto" el archivo que recibe como un XML, buscando la estructura XML dentro de los archivos, y obviamente como estamos recibiendo un archivo de texto pues el error siempre se encontrara presente, por lo tanto que tenemos que hacer un unparsed para que el archivo sea leído como un texto y de esa manera no busque caracteres XML dentro de los archivos. Quedando de la siguiente manera.

collection('file:///C:/Users/Quality/Documents/ProyectoComerciales/download_files/?select=*.txt;unparsed=yes')

Posteriormente, únicamente es cuestión de manipular esa colección de archivos de texto. Les dejo el ejemplo completo.

Código:
<xsl:for-each select="collection('file:///C:/Users/Quality/Documents/ProyectoComerciales/download_files/?select=*.txt;unparsed=yes')">
	<xsl:value-of select="tokenize(document-uri(.), '/')[last()]"/>
</xsl:for-each>
Cualquier duda y/o comentario, estoy atento a sus comentarios.

Que tengan un excelente día.

Etiquetas: multiples, xml
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 16:26.