2010-07-07 8 views
8

Tengo algunas transformaciones XSLT 2.0 complejas. Estoy tratando de averiguar si hay una forma de propósito general para garantizar que no se emitan etiquetas vacías. Entonces ... conceptualmente, una etapa final de procesamiento que recursivamente elimina todas las etiquetas vacías. Entiendo que esto podría hacerse mediante un XSLT separado que no hizo más que filtrar las etiquetas vacías, pero necesito que todo esté empaquetado en una sola.Procesamiento en dos fases: No generar etiquetas vacías desde la fase 1 Procesamiento XSLT 2.0

+0

excelente pregunta (1). Ver mi respuesta para una solución detallada. –

Respuesta

8

Este XSLT 2.0 transformación ilustra cómo multi-pass (en este 2-pass caso) de procesamiento se puede hacer:

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

<xsl:template match="node()|@*" mode="#all"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*" mode="#current"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="/"> 
    <xsl:variable name="vPass1"> 
    <xsl:apply-templates/> 
    </xsl:variable> 

    <xsl:apply-templates select="$vPass1/*" mode="non-empty"/> 
</xsl:template> 

<xsl:template match="text()[xs:integer(.) mod 2 eq 0]"/> 

<xsl:template match="*[not(node())]" mode="non-empty"/> 
</xsl:stylesheet> 

cuando se aplica en este documento XML:

<nums> 
    <num>01</num> 
    <num>02</num> 
    <num>03</num> 
    <num>04</num> 
    <num>05</num> 
    <num>06</num> 
    <num>07</num> 
    <num>08</num> 
    <num>09</num> 
    <num>10</num> 
</nums> 

Crea un documento de resultados en el primer pase (que se captura en la variable $vPass1), en el que todos los elementos <num> con contenido incluso intege Se eliminan sus contenidos y están vacíos. Luego, en el segundo pase, aplicado en un modo específico, se eliminan todos los elementos vacíos.

El resultado de la transformación es:

<nums> 
    <num>01</num> 
    <num>03</num> 
    <num>05</num> 
    <num>07</num> 
    <num>09</num> 
</nums> 

hacer la nota el uso de modos, y los modos especiales #all y #current.

Actualización: El OP ahora quiere en un comentario para eliminar "recursivamente" "todos los nodos que no tienen un descendiente no vacío".

Esto se puede implementar de manera más sencilla sin recurrencia explícita. Sólo cambia:

<xsl:template match="*[not(node())]" mode="non-empty"/> 

a:

<xsl:template match="*[not(descendant::text())]" mode="non-empty"/> 
+0

Responde a la pregunta general, pero falta una parte específica: eliminar recursivamente todas las etiquetas vacías ... así que solo necesito cambiar "* [not (node ​​())]" por una expresión apropiada que signifique todo nodos que no tienen un descendiente no vacío – mentics

+0

@taotree La próxima vez formule su pregunta mejor. :) Creo que es mejor hacer de este nuevo requisito una pregunta por separado, también sería una excelente pregunta. Puede utilizar para el patrón de coincidencia de la plantilla vacía esto: '* [not (descenddant :: text())]' –

+0

@taotree Actualizó la respuesta para reflejar su nuevo requisito ... :) –

Cuestiones relacionadas