A la hora de obtener el XML de un formulario, Webforms provee dos mecanismos: generar un xml a partir del jsonData de un formulario o utilizar una plantilla de XML cuyos elementos serán sustituidos en función del jsonData proporcionado. 

Referenciar elementos del formulario en la plantilla XML.

Al generar un documento XML, a partir de una plantilla, se sustituirán las referencias a los elementos del formulario por el valor que se haya introducido en el campo, es decir, su valor en el JSON Data.

Podemos referenciar elementos de tipo input, desplegable, checkbox o radio mediante la siguiente sintaxis:

{{idElemento}}
XML

Mientras que los iteradores y las tablas, primero haremos referencia al iterador seguido de un punto (.) y a continuación el nombre del campo. Se configuran de la siguiente manera:

{{idIterador.idElemento}}
XML

Elementos del formulario como elementos en el fichero XML

En el caso de trasladar los campos del formulario diseñados con elementos de Webforms , a una plantilla XML para que se lean también como elementos del XML, usaremos la siguiente configuración:

<solicitante>
	<nombre>{{PersonaFisica-nombre}}</nombre>
	<apellido1>{{PersonaFisica-apellido-1}}</apellido1>
	<apellido2>{{PersonaFisica-apellido-2}}</apellido2>
	<edad>{{PersonaFisica-edad}}</edad>
</solicitante>
XML

A continuación vemos un ejemplo en el caso de incluir en la plantilla tablas o iteradores, como elementos del XML:

<solicitantes>
	<solicitante>
		<nombre>{{Solicitante.PersonaFisica-nombre}}</nombre>
		<apellido1>{{Solicitante.PersonaFisica-apellido-1}}</apellido1>
		<apellido2>{{Solicitante.PersonaFisica-nombre-2}}</apellido2>
		<edad>{{Solicitante.PersonaFisica-edad}}</edad>
	</solicitante>
</solicitantes>
XML

Al tratarse de una tabla/iterador, puede tener n filas/iteraciones lo que dará lugar a n repeticiones de la etiqueta que engloba a los elementos de la iteración. Por ejemplo;

<solicitantes>
	<solicitante>
		<nombre>Aitana</nombre>
		<apellido1>Vazquez</apellido1>
		<apellido2>Mora</apellido2>
		<edad>38</edad>
	</solicitante>
	<solicitante>
		<nombre>Mateo</nombre>
		<apellido1>Serra</apellido1>
		<apellido2>León</apellido2>
		<edad>27</edad>
	</solicitante>
<solicitantes>
XML

Niveles de anidamiento adicionales

A partir de la versión 6.2.0

En ocasiones querremos que el XML de salida tenga niveles de anidamiento adicionales. Por ejemplo en el siguiente ejemplo, no queremos repetir la sección

<solicitantes>
	<solicitante>
		<seccion>
			<nombre>{{Solicitante.PersonaFisica-nombre}}</nombre>
			<apellido1>{{Solicitante.PersonaFisica-apellido-1}}</apellido1>
			<apellido2>{{Solicitante.PersonaFisica-nombre-2}}</apellido2>
			<edad>{{Solicitante.PersonaFisica-edad}}</edad>
		</seccion>
	</solicitante>
</solicitantes>
XML

Pero de normal, es el resultado que obtendríamos:

<solicitantes>
	<solicitante>
		<seccion>
			<nombre>Aitana</nombre>
			<apellido1>Vazquez</apellido1>
			<apellido2>Mora</apellido2>
			<edad>38</edad>
		</seccion>
 		<seccion>
	        <nombre>Mateo</nombre>
			<apellido1>Serra</apellido1>
			<apellido2>León</apellido2>
			<edad>27</edad>
		</seccion>
	</solicitante>
<solicitantes>
XML

Para evitar eso, debemos añadir la propiedad wf:type="section" y el namespace para usarla xmlns:wf="https://webforms.es"

<solicitantes xmlns:wf="https://webforms.es">
	<solicitante>
		<seccion wf:type="section">
			<nombre>{{Solicitante.PersonaFisica-nombre}}</nombre>
			<apellido1>{{Solicitante.PersonaFisica-apellido-1}}</apellido1>
			<apellido2>{{Solicitante.PersonaFisica-nombre-2}}</apellido2>
			<edad>{{Solicitante.PersonaFisica-edad}}</edad>
		</seccion>
	</solicitante>
</solicitantes>
XML

Esto indicará a webforms que se trata de una sección y que por tanto, no es el elemento que ha de repetir, transformandolo entonces en:

<solicitantes xmlns:wf="https://webforms.es">
	<solicitante>
		<seccion wf:type="section">
			<nombre>Aitana</nombre>
			<apellido1>Vazquez</apellido1>
			<apellido2>Mora</apellido2>
			<edad>38</edad>
		</seccion>
	</solicitante>
	<solicitante>
 		<seccion wf:type="section">
	        <nombre>Mateo</nombre>
			<apellido1>Serra</apellido1>
			<apellido2>León</apellido2>
			<edad>27</edad>
		</seccion>
	</solicitante>
<solicitantes>
XML

Elementos de una iteración concreta

Podemos hacer referencia a un elemento específico de una iteración/fila concreta de un iterador/tabla, mediante la siguiente sintaxis:

{{idIterador[indiceIteracion].idElemento}}
XML

De esta forma, podemos referenciar el elemento de una fila/iteración sin necesidad de que se generen n repeticiones, una por cada fila/iteración.

<nombrePrimerInteresado>{{Solicitante[0].PersonaFisica-nombre}}</nombreInteresado>
<edadSegundoInteresado>{{Solicitante[1].PersonaFisica-edad}}</edadSegundoInteresado>
XML

Elementos del formulario como atributos de un elemento XML

En las plantillas XML también es posible configurar elementos del formulario Webforms como atributos de un elemento XML. Para ello, las referencias al elementos son similares y lo único que cambia es la ubicación en el atributo del elemento XML. 

Un ejemplo de elementos básicos de Webforms configurados como atributos del elemento XML, es el siguiente:

<solicitante NOM="{{PersonaFisica-nombre}}" APE1="{{PersonaFisica-apellido-1}}" APE2="{{PersonaFisica-apellido-2}}" EDAD="{{PersonaFisica-edad}}">
</solicitante>
XML

Igualmente, podemos incluir como atributos también elementos de Webforms como iteradores o tablas:

<solicitante NOM="{{Solicitante.PersonaFisica-nombre}}" APE1="{{Solicitante.PersonaFisica-apellido-1}}" APE2="{{Solicitante.PersonaFisica-apellido-2}}" EDAD="{{Solicitante.PersonaFisica-edad}}">
</solicitante>
XML


Proporcionar formato a los elementos referenciados en la plantilla

Además de la configuración de los elementos de Webforms, en las plantillas XML podemos proporcionar formato a dichos elementos para que tengan el aspecto adecuado en el XML de salida y puedan ser consumidos por aplicaciones que tengan determinadas restricciones.

La configuración para proporcionar un formato al campo, por ejemplo para que se muestren todos los caracteres en mayúsculas a la salida, es mediante la siguiente sintaxis:

{{idElemento | uppercase}}
XML

Y en el caso de que el elemento se encuentre dentro de un iterador o tabla, la estructura es similar:

{{idIterador.idElemento | uppercase}}
XML

Los formatos disponibles para campos referenciados en plantillas, son los siguientes:

FormatoDescripción
uppercaseLos caracteres del contenido del campo se muestra en mayúsculas.
lowercaseLos caracteres del contenido del campo se muestra en minúsculas.
stripAccentsElimina los signos ortográficos del contenido del campo.
stripAccentsExcept 'áÑ'Elimina los signos ortográficos del contenido del campo salvo los contenidos en la expresión, en este caso se exceptuarían los casos donde aparecen la á y la Ñ pero sí eliminaría la Á.
format '%.Nf'En los campos de tipo número con decimales, proporciona tantos decimales como el valor que se le indica en la "N". Ej. format '%.2f'
clean '[^0-9A-ZÑ ,\.-]'Elimina los caracteres definidos en la expresión regular indicada.
xmlfy
Permite la inserción de código XML, de modo que sea tratado como tal y no como texto.

Un ejemplo básico que proporciona texto en mayúsculas a varios elementos en la plantilla XML, es el siguiente:

<solicitantes>
	<solicitante>
		<nombre>{{Solicitante.PersonaFisica-nombre | uppercase}}</nombre>
		<apellido1>{{Solicitante.PersonaFisica-apellido-1 | uppercase}}</apellido1>
		<apellido2>{{Solicitante.PersonaFisica-nombre-2 | uppercase}}</apellido2>
		<edad>{{Solicitante.PersonaFisica-edad | uppercase}}</edad>
	</solicitante>
<solicitantes>
XML

El comportamiento en el caso de configurarse los elementos del formulario Webforms como atributos, es similar:

<solicitante NOM="{{PersonaFisica-nombre | uppercase}}" APE1="{{PersonaFisica-apellido-1 | uppercase}}" APE2="{{PersonaFisica-apellido-2 | uppercase}}" >
</solicitante>
XML

Un ejemplo para la inserción de código XML a través de un campo sería el siguiente

<contenedor>
   {{campo-xml | xmlfy}}
</contenedor>
XML

En caso de que el campo que contiene el XML a insertar sea un iterador, debe indicarse en el mismo

<contenedor wf:type="iteration">>
   {{campo-xml | xmlfy}}
</contenedor>
XML

Ejemplo de formulario con fragmento que hace uso de una plantilla de DocumentBuilder

Soporte a XSLT

A partir de la versión 6.5.0

XSLT es un estandar que permite transformar un XML. Es muy complejo pero muy potente https://www.mclibre.org/consultar/xml/lecciones/xml-xslt.html y puede proveer de funcionalidades muy específicas.

Webforms permite incrustar una hoja de estilos XSLT dentro de la plantilla XML. Dicha hoja de estilos será procesada como paso final antes de devolver el XML, antes de realizar la sustitución de variables y modificaciones de formatos realizados en pasos anteriores.

Ejemplo de XSLT que elimina etiquetas vacías

Por ejemplo supongamos que partimos de esta plantilla:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<FORMULARIO>
  <SOLICITA>{{Solicita}}</SOLICITA>
  
  <REPRESENTANTE>
    <PERSONA_FISICA 
      NIF="{{Solicitante-solicitantes.RepresentantePersonaFisica-nif}}" />
  </REPRESENTANTE>

</FORMULARIO>
CODE

Que nos devuelve esto si no tenemos el campo nif relleno:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<FORMULARIO>
  <SOLICITA>Lorem ipsum</SOLICITA>
  
  <REPRESENTANTE>
    <PERSONA_FISICA NIF="" />
  </REPRESENTANTE>

</FORMULARIO>
CODE

Si nuestro backoffice no es capaz de procesar ese XML tendríamos un problema. Es posible que necesitemos eliminar REPRESENTANTE en este caso. Para ello, modificamos nuestra plantilla y configuramos una hoja XSLT que será procesada durante la generación del XML

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="#filter"?>
<FORMULARIO>
  
  <!-- Hoja de estilo XSLT incrustada -->
  <xsl:stylesheet id="filter" version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    
    <!-- Copiar todo REPRESENTANTE con PERSONA_FISICA con NIF vacío -->
    <xsl:template match="@*|node()">
      <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
    </xsl:template>
    
    <!-- Eliminar REPRESENTANTE con PERSONA_FISICA con NIF vacío -->    
    <xsl:template match="REPRESENTANTE[PERSONA_FISICA[@NIF='']]"/>
  </xsl:stylesheet>
  
  <SOLICITA>{{Solicita}}</SOLICITA>
  
  <REPRESENTANTE>
    <PERSONA_FISICA 
      NIF="{{Solicitante-solicitantes.RepresentantePersonaFisica-nif}}" />
  </REPRESENTANTE>

</FORMULARIO>
CODE

El mismo json pasaría de volvernos:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="#filter"?>
<FORMULARIO>
  
  <xsl:stylesheet id="filter" version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:template match="@*|node()">
      <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
    </xsl:template>
    
    <xsl:template match="REPRESENTANTE[PERSONA_FISICA[@NIF='']]"/>
  </xsl:stylesheet>
  
  <SOLICITA>Lorem Ipsum</SOLICITA>  

</FORMULARIO>
CODE