Inicio ¿Qué es XSL-FO?
Artículo
Cancelar

¿Qué es XSL-FO?

Introducción

Un documento XSL-FO es un documento XML en el que se especifica cómo se van a formatear unos datos para presentarlos en pantalla, papel u otros medios.

El objetivo de este lenguaje es parecido al de CSS, definir la forma en la que deberá mostrarse un documento XML por pantalla (o papel).

Flujo de trabajo con XSL-FO Flujo de trabajo con XSL-FO

¿Qué extensión deben tener los ficheros XSL-FO?

Estructura de un documento XSL-FO

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

  <fo:layout-master-set>

    <fo:simple-page-master master-name="A4">
      <!-- La plantilla de la hoja va aquí -->
    </fo:simple-page-master>

  </fo:layout-master-set>

  <fo:page-sequence master-reference="A4">
    <!-- El contenido de la página va a aquí -->
  </fo:page-sequence>

</fo:root>
  • Espacio de nombres: http://www.w3.org/1999/XSL/Format
  • Elemento raíz: fo:root
  • Organización visual del documento:
    • Modelos de página: “páginas maestras”
      • Se definen dentro de fo:layout-master-set
      • Sólo un tipo de página maestra, fo:simple-page-master, que es una página rectangular.
    • Las páginas del documento harán referencia a las páginas maestras que se hayan definido, y heredarán sus propiedades.

Elemento fo:simple-page-master

Atributos del elemento fo:simple-page-master:

  • master-name
  • page-height
  • page-width
  • margin-left, margin-top, margin-right, margin-bottom

Diagrama atributos elemento fo:simple-page-master Diagrama atributos elemento fo:simple-page-master

Ejemplo:

1
2
3
4
5
6
<fo:layout-master-set>
  <fo:simple-page-master master-name="pagina-normal" page-height="29.7cm" 
  page-width="21cm" margin-left="3cm" margin-right="3cm"  margin-top="2cm" 
  margin-bottom="2cm">
  </fo:simple-page-master>
</fo:layout-master-set>

Elemento fo:page-sequence

Representa una secuencia de páginas y hace referencia a modelo de página.

Recuerda que el atributo master-reference debe haberse definido en layout-master-set.

Elementos hijo de fo:page-sequence:

  • fo:title (opcional): Título de la página
  • fo:static-content: Texto que se repite en todas las páginas. También puede contener elementos que se repiten aunque se calculen en cada una (como el número de página).
  • fo:flow: Contenidos de las páginas, se incluyen en secuencia

Tiene 8 atributos opcionales para indicar cómo se pagina la secuencia:

  • fo:initial-page-number
  • fo:force-page-count
  • fo:format
  • fo:letter-value
  • fo:country
  • fo:language
  • fo:grouping-separator
  • fo:grouping-size

Regiones

  • region-body (requerido): Cuerpo de la página.
  • region-before (opcional): Cabecera de la página.
  • region-after (opcional): Pie de la página.
  • region-start (opcional): Columna izquierda de la página.
  • region-end (opcional): Columna derecha de la página.

Ejemplo:

1
2
3
4
5
6
7
8
9
<fo:layout-master-set>
  <fo:simple-page-master master-name="pagina-normal" page-height="29.7cm"
      page-width="21cm" margin-left="3cm" margin-right="3cm" margin-top="2cm" 
      margin-bottom="2cm">
    <fo:region-before extent="1cm"/>
    <fo:region-body margin-top="1cm" margin-bottom="1cm"/>
    <fo:region-after extent="1cm"/>
  </fo:simple-page-master>
</fo:layout-master-set>

Modelo de formateo

Cajas rectangulares, llamadas áreas, que pueden contener:

  • Texto
  • Espacio vacío
  • Imágenes
  • Otros objetos de formateo

Las cajas tienen bordes y márgenes.

Hay 4 tipos de áreas, representados en el siguiente diagrama:

Estructura de las áreas Estructura de las áreas

Elemento fo:flow

Contiene el “contenido real” de las páginas. Es una secuencia de elementos fo:block, fo:block-container, fo:table-and-caption, fo:table, y fo:list-block.

Atributo flow-name: Indica en qué región de la página va el contenido. Valores posibles:

  • xsl-region-body
  • xsl-region-before
  • xsl-region-after
  • xsl-region-start
  • xsl-region-end

Elemento fo:static-content

El contenido aparecerá en cada secuencia de página.

Ejemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<fo:root>
  <fo:layout-master-set>
    <fo:simple-page-master master-name="miPágina"
      margin="2cm">
      <fo:region-body margin="2cm" />
      <fo:region-before extent="2cm" />
    </fo:simple-page-master>
  </fo:layout-master-set>
  <fo:page-sequence master-reference="miPágina">
    <fo:static-content flow-name="xsl-region-before"
      font-style="italic" font-size="10pt" font-family="Times">
      <fo:block text-align="start"
        background-color="blue" color="white"> Página <fo:page-number />
      </fo:block>
    </fo:static-content>
    <fo:flow flow-name="xsl-region-body">
      <fo:block>Hola con cabecera</fo:block>
    </fo:flow>
  </fo:page-sequence>
</fo:root>

Resultado:

Salida usando fo:static-content Salida usando fo:static-content

Listas

Ejemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<fo:list-block>
  <fo:list-item>
    <fo:list-item-label end-indent="label-end()">
      <fo:block>&#x2022;</fo:block>
    </fo:list-item-label>
    <fo:list-item-body start-indent="body-start()">
      <fo:block>Primer elemento</fo:block>
    </fo:list-item-body>
  </fo:list-item>
  <fo:list-item>
    <fo:list-item-label end-indent="label-end()">
      <fo:block>&#x2022;</fo:block>
    </fo:list-item-label>
    <fo:list-item-body start-indent="body-start()">
      <fo:block>Segundo elemento</fo:block>
    </fo:list-item-body>
  </fo:list-item>
</fo:list-block>

Resultado:

Salida de lista Salida de lista

Tablas

Ejemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<fo:table border="0.5pt solid"
  text-align="center"
  table-layout="fixed">
  <fo:table-column column-width="5cm" />
  <fo:table-column column-width="5cm" />
  <fo:table-body>
    <fo:table-row>
      <fo:table-cell padding="6pt" border="0.5pt solid">
        <fo:block> Uno . Uno </fo:block>
      </fo:table-cell>
      <fo:table-cell padding="6pt" border="0.5pt solid">
        <fo:block> Uno . Dos </fo:block>
      </fo:table-cell>
    </fo:table-row>
    <fo:table-row>
      <fo:table-cell padding="6pt" border="0.5pt solid">
        <fo:block> Dos . Uno </fo:block>
      </fo:table-cell>
      <fo:table-cell padding="6pt"
        border="0.5pt solid">
        <fo:block> Dos . Dos </fo:block>
      </fo:table-cell>
    </fo:table-row>
  </fo:table-body>
</fo:table>

Resultado:

Salida de tabla Salida de tabla

Mantener el formato

Para mantener el formato podemos usar el bloque CDATA como se ve en el siguiente ejemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
<fo:block
  font-family="monospace"
  white-space-collapse="false"
  wrap-option="no-wrap"
  linefeed-treatment="preserve"
  white-space-treatment="preserve">
<![CDATA[
<pedido> <producto id="G34">
<nombre>Grapadora</nombre>
</producto>
</pedido>
]]>
</fo:block>

Salida:

1
2
3
4
5
<pedido>
  <producto id="G34">
    <nombre>Grapadora</nombre>
  </producto>
</pedido>

Enlaces e imágenes

Enlaces:

1
2
<fo:basic-link external-destination="..." />
<fo:basic-link internal-destination="valorID" />

Cada bloque puede tener un atributo ID.

Referencias a páginas:

1
<fo:page-number-citation ref-id="valorID" />

Gráficos:

1
<fo:external-graphic src="url('smile.gif')" content-height="1em" content-width="1em"/>

Otras características

  1. Notas a pie de página: footnote
  2. Marcadores (marker, retrieve-marker). Por ejemplo, incluir nombre del capítulo en la cabecera.
  3. Líneas guía: fo:leader
  4. Elementos fo:float, sin posición absoluta
  5. Orientación de escritura: reference-orientation
  6. Bidireccionalidad (izqda a dcha y dcha a izqda)

Ejemplos XSL-FO

Ejemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

  <fo:layout-master-set>
    <fo:simple-page-master master-name="ejemploHolaMundo">
      <fo:region-body margin="1in" />
    </fo:simple-page-master>
  </fo:layout-master-set>

  <fo:page-sequence master-reference="ejemploHolaMundo">
    <fo:flow flow-name="xsl-region-body">
      <fo:block>Hola mundo!</fo:block>
    </fo:flow>
  </fo:page-sequence>

</fo:root>

Otro ejemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

  <fo:layout-master-set>
    <fo:simple-page-master master-name="simple" page-height="29.7cm" page-width="21cm"
      margin-top="1cm" margin-bottom="2cm" margin-left="2.5cm" margin-right="2.5cm">
      <fo:region-body margin-top="3cm" />
      <fo:region-before extent="3cm" />
      <fo:region-after extent="1.5cm" />
    </fo:simple-page-master>
  </fo:layout-master-set>

  <fo:page-sequence master-reference="simple">
    <fo:flow flow-name="xsl-region-body">

      <fo:block font-size="18pt" font-family="sans-serif" line-height="24pt"
        space-after.optimum="15pt" text-align="center" padding-top="3pt">
        Mi segundo XSL-FO
      </fo:block>

      <fo:block font-size="12pt" font-family="sans-serif" line-height="15pt"
        space-after.optimum="3pt" text-align="justify">
        Hola este es mi segundo XSL-FO.
      </fo:block>

    </fo:flow>
  </fo:page-sequence>
</fo:root>

Procesadores XSL-FO

Se recomienda usar Apache™ FOP.

En GNU/Linux con variables de entorno configuradas:

Si quieres saber que son las variables de entorno y como se configuran, lee el artículo Tutorial: La variable de entorno Path

Si no tenemos las variables de entorno configuradas el ejecutable fop o fop.bat deberá estar en la misma carpeta donde esté <docExistente.fo>.

1
$fop -fo <docExistente.fo> -pdf <docGenerado.pdf>

En GNU/Linux sin variables de entorno configuradas:

1
$./fop -fo <docExistente.fo> -pdf <docGenerado.pdf>

En Windows con variables de entorno configuradas:

1
fop.bat -fo <docExistente.fo> -pdf <docGenerado.pdf>

En Windows sin variables de entorno configuradas :

1
./fop.bat -fo <docExistente.fo> -pdf <docGenerado.pdf>

XSLT + XSL-FO

XSLT y XSL-FO pueden trabajar conjuntamente como se muestra en la siguiente imagen:

Funcionamiento de XSLT y XLS-FO en secuencia Funcionamiento de XSLT y XLS-FO en secuencia

  • Con el procesador XSLT generamos un fichero XSL-FO.
  • El fichero XSL-FO es procesado por el procesador XSL-FO generando un documento que puede ser leído cómodamente por una persona.

Utilizaríamos un comando para generar el XLS-FO de los datos XML:

1
java -jar "C:\Program Files\SaxonHE12-4J\saxon-he-12.4.jar" -xsl:xslt.xsl -s:datos.xml -o:xslfo.xsl

Para luego generar el PDF con Apache FOP:

1
fop.bat -fo xslfo.xsl -pdf pdf.pdf

Estos dos pasos se pueden condensar en uno de la siguiente manera:

1
fop -xml datos.xml -xsl xslt.xsl -pdf pdf.pdf

Bibliografía

Este artículo está licenciado bajo CC BY 4.0 por el autor.

¿Qué es XSLT?

Casos prácticos sobre aprendizaje automático