Antes que nada cabe mencionar que el siguiente stylesheet(xsl) es producto de la necesidad de hacer una limpieza a todos aquellos nodos que al momento de procesar no aportan valor alguno, y que a su vez en el respectivo esquema (XSD) dichos campos se encuentren como opcionales, ya que si en la firma se encuentran como obligatorios lo ideal es no eliminarlos.
Partiendo de esta necesidad, se realiza xsl que permita dicha conversión como explicación general, el siguiente codigo utiliza recursividad, partiendo de que existen basicamente 2 tipos de nodos, Nodos complejos y Nodos simples, siendo asi se realiza un recorrido RECURSIVO teniendo en cuenta si el nodo seleccionado tiene nodos Hijos, si este tiene hijos es por que es un nodo complejo, por ende se hace un llamado a el template nodoPadre en caso contrario se realizara un llamado a el template templateNodo el cual se aplica a los Nodos simples. de esta manera se va construyendo de forma recursiva el xml completo.
El sgte stylesheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
exclude-result-prefixes="exsl">
<!--=================================================================-->
<!-- Transformacion para Borrar Nodos VACIOS en xml -->
<!-- Tomado de Datobyte.blogSpot.com -->
<!-- Desarrollado por Wilfer Giraldo -->
<!--=================================================================-->
<xsl:output method="xml" omit-xml-declaration="yes" />
<xsl:template match="/">
<xsl:variable name="cargaTemp">
<xsl:call-template name="nodoPadre">
<xsl:with-param name="nombreNodo" select="name(./*)" />
<xsl:with-param name="nameSpaceInput" select="namespace-uri(./*)" />
<xsl:with-param name="datoNodo" select="./*" />
<xsl:with-param name="hijos" select="count(./*/child::*)" />
</xsl:call-template>
</xsl:variable>
<xsl:copy-of select="exsl:node-set($cargaTemp)/extra/*" />
</xsl:template>
<xsl:template name="nodoPadre">
<xsl:param name="nombreNodo" />
<xsl:param name="nameSpaceInput" />
<xsl:param name="datoNodo" />
<xsl:param name="hijos" />
<xsl:choose>
<xsl:when test="$hijos > 0 ">
<xsl:variable name="contenido">
<xsl:for-each select="$datoNodo/child::*">
<xsl:variable name="cargaTemp">
<xsl:call-template name="nodoPadre">
<xsl:with-param name="nombreNodo" select="name()" />
<xsl:with-param name="nameSpaceInput" select="namespace-uri()" />
<xsl:with-param name="datoNodo" select="." />
<xsl:with-param name="hijos" select="count(*)" />
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$cargaTemp != ''">
<extra>
<xsl:copy-of select="exsl:node-set($cargaTemp)/extra/*" />
</extra>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:variable>
<xsl:choose>
<xsl:when test="$contenido != ''">
<extra>
<xsl:element name="{$nombreNodo}" namespace="{$nameSpaceInput}">
<xsl:copy-of select="exsl:node-set($contenido)/extra/*" />
</xsl:element>
</extra>
</xsl:when>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="contenido2" >
<xsl:value-of select="$datoNodo" />
</xsl:variable>
<xsl:variable name="contenido">
<extra>
<xsl:call-template name="templateNodo">
<xsl:with-param name="nombreNodo" select="$nombreNodo" />
<xsl:with-param name="datoNodo" select="$contenido2" />
<xsl:with-param name="nameSpaceInput" select="$nameSpaceInput" />
</xsl:call-template>
</extra>
</xsl:variable>
<extra>
<xsl:copy-of select="exsl:node-set($contenido)/extra/*" />
</extra>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="templateNodo">
<xsl:param name="nombreNodo" />
<xsl:param name="datoNodo" />
<xsl:param name="nameSpaceInput" />
<xsl:choose>
<xsl:when test="$datoNodo != ''">
<xsl:element name="{$nombreNodo}" namespace="{$nameSpaceInput}">
<xsl:value-of select="$datoNodo" />
</xsl:element>
</xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
exclude-result-prefixes="exsl">
<!--=================================================================-->
<!-- Transformacion para Borrar Nodos VACIOS en xml -->
<!-- Tomado de Datobyte.blogSpot.com -->
<!-- Desarrollado por Wilfer Giraldo -->
<!--=================================================================-->
<xsl:output method="xml" omit-xml-declaration="yes" />
<xsl:template match="/">
<xsl:variable name="cargaTemp">
<xsl:call-template name="nodoPadre">
<xsl:with-param name="nombreNodo" select="name(./*)" />
<xsl:with-param name="nameSpaceInput" select="namespace-uri(./*)" />
<xsl:with-param name="datoNodo" select="./*" />
<xsl:with-param name="hijos" select="count(./*/child::*)" />
</xsl:call-template>
</xsl:variable>
<xsl:copy-of select="exsl:node-set($cargaTemp)/extra/*" />
</xsl:template>
<xsl:template name="nodoPadre">
<xsl:param name="nombreNodo" />
<xsl:param name="nameSpaceInput" />
<xsl:param name="datoNodo" />
<xsl:param name="hijos" />
<xsl:choose>
<xsl:when test="$hijos > 0 ">
<xsl:variable name="contenido">
<xsl:for-each select="$datoNodo/child::*">
<xsl:variable name="cargaTemp">
<xsl:call-template name="nodoPadre">
<xsl:with-param name="nombreNodo" select="name()" />
<xsl:with-param name="nameSpaceInput" select="namespace-uri()" />
<xsl:with-param name="datoNodo" select="." />
<xsl:with-param name="hijos" select="count(*)" />
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$cargaTemp != ''">
<extra>
<xsl:copy-of select="exsl:node-set($cargaTemp)/extra/*" />
</extra>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:variable>
<xsl:choose>
<xsl:when test="$contenido != ''">
<extra>
<xsl:element name="{$nombreNodo}" namespace="{$nameSpaceInput}">
<xsl:copy-of select="exsl:node-set($contenido)/extra/*" />
</xsl:element>
</extra>
</xsl:when>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="contenido2" >
<xsl:value-of select="$datoNodo" />
</xsl:variable>
<xsl:variable name="contenido">
<extra>
<xsl:call-template name="templateNodo">
<xsl:with-param name="nombreNodo" select="$nombreNodo" />
<xsl:with-param name="datoNodo" select="$contenido2" />
<xsl:with-param name="nameSpaceInput" select="$nameSpaceInput" />
</xsl:call-template>
</extra>
</xsl:variable>
<extra>
<xsl:copy-of select="exsl:node-set($contenido)/extra/*" />
</extra>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="templateNodo">
<xsl:param name="nombreNodo" />
<xsl:param name="datoNodo" />
<xsl:param name="nameSpaceInput" />
<xsl:choose>
<xsl:when test="$datoNodo != ''">
<xsl:element name="{$nombreNodo}" namespace="{$nameSpaceInput}">
<xsl:value-of select="$datoNodo" />
</xsl:element>
</xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Aplicado al sgte XML:
<db:datos xmlns:db="datobyte.blogspot.com">
<ubicacionFuente>
<pais>Colombia</pais>
<departamento/>
<municipio/>
</ubicacionFuente>
<nombrePersona>
<primerNombre>WILFER</primerNombre>
<segundoNombre/>
<primerApellido>GIRALDO </primerApellido>
<segundoApellido/>
</nombrePersona>
<sexo>MASCULINO</sexo>
<email/>
<blog>datobyte.blogspot.com</blog>
</db:datos>
<ubicacionFuente>
<pais>Colombia</pais>
<departamento/>
<municipio/>
</ubicacionFuente>
<nombrePersona>
<primerNombre>WILFER</primerNombre>
<segundoNombre/>
<primerApellido>GIRALDO </primerApellido>
<segundoApellido/>
</nombrePersona>
<sexo>MASCULINO</sexo>
<email/>
<blog>datobyte.blogspot.com</blog>
</db:datos>
Obtiene Como resultado el Sgte XML:
<db:datos xmlns:db="datobyte.blogspot.com">
<ubicacionFuente>
<pais>Colombia</pais>
</ubicacionFuente>
<nombrePersona>
<primerNombre>WILFER</primerNombre>
<primerApellido>GIRALDO </primerApellido>
</nombrePersona>
<sexo>MASCULINO</sexo>
<blog>datobyte.blogspot.com</blog>
</db:datos>
<ubicacionFuente>
<pais>Colombia</pais>
</ubicacionFuente>
<nombrePersona>
<primerNombre>WILFER</primerNombre>
<primerApellido>GIRALDO </primerApellido>
</nombrePersona>
<sexo>MASCULINO</sexo>
<blog>datobyte.blogspot.com</blog>
</db:datos>
No hay comentarios:
Publicar un comentario