xsl with sort condicional choose xml xslt filter

xml - with - xslt condicional



Filtro XML basado en otro xml usando XSLT 1 (3)

Aquí está la transformación requerida:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:z="inline:text.xml" exclude-result-prefixes="z" > <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <z:filter> <Root> <E1 a="1"></E1> <E2></E2> <E5> <SE51></SE51> <SE52></SE52> </E5> </Root> </z:filter> <xsl:variable name="vFilter" select= "document('''')/*/z:filter"/> <xsl:template match="/"> <xsl:apply-templates select="*[name()=name($vFilter/*)]"> <xsl:with-param name="pFiltNode" select="$vFilter/*"/> </xsl:apply-templates> </xsl:template> <xsl:template match="*"> <xsl:param name="pFiltNode"/> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:for-each select="text() | *"> <xsl:choose> <xsl:when test="self::text()"> <xsl:copy-of select="."/> </xsl:when> <xsl:otherwise> <xsl:variable name="vFiltNode" select="$pFiltNode/*[name()=name(current())]"/> <xsl:apply-templates select="self::node()[$vFiltNode]"> <xsl:with-param name="pFiltNode" select="$vFiltNode"/> </xsl:apply-templates> </xsl:otherwise> </xsl:choose> </xsl:for-each> </xsl:copy> </xsl:template> </xsl:stylesheet>

Cuando se aplica esta transformación en el siguiente documento XML (el original más la adición de <SE511>SEV11</SE511> para demostrar que el filtrado funciona en cualquier nivel :

<Root> <E1 a="1">V1</E1> <E2>V2</E2> <E3>V3</E3> <E5> <SE51>SEV1</SE51> <SE511>SEV11</SE511> <SE52>SEV2</SE52> </E5> <E6> <SE61>SEV3</SE61> <SE62>SEV4</SE62> </E6> </Root>

el resultado deseado es producido :

<Root> <E1 a="1">V1</E1> <E2>V2</E2> <E3>V3</E3> <E5> <SE51>SEV1</SE51> <SE511>SEV11</SE511> <SE52>SEV2</SE52> </E5> <E6> <SE61>SEV3</SE61> <SE62>SEV4</SE62> </E6> </Root>

Observe los siguientes detalles de esta solución:

  1. Las plantillas se aplican solo a los elementos que tienen un nodo coincidente en el documento de filtro y también a todos los nodos de texto de dichos elementos.
  2. La plantilla que coincide con un elemento se pasa como parámetro al nodo correspondiente en el documento de filtro.
  3. Al aplicar plantillas a un elemento-hijo, su nodo correspondiente se encuentra y pasa como el parámetro esperado.

¡Disfruta!

¿Cómo filtramos un documento xml basado en otro documento xml? Tengo que eliminar todos los elementos que no están en el XML de búsqueda. Tanto la entrada xml como la búsqueda xml tienen los mismos elementos raíz, estamos usando XSLT 1.0.

Entrada ex

<Root> <E1 a="1">V1</E1> <E2>V2</E2> <E3>V3</E3> <E5> <SE51>SEV1</SE51> <SE52>SEV2</SE52> </E5> <E6> <SE61>SEV3</SE61> <SE62>SEV4</SE62> </E6> </Root>

Filtro Xml

<Root> <E1 a="1"></E1> <E2></E2> <E5> <SE51></SE51> <SE52></SE52> </E5> </Root>

Rendimiento esperado

<Root> <E1 a="1">V1</E1> <E2>V2</E2> <E5> <SE51>SEv1</SE51> <SE52>SEV2</SE52> </E5> </Root>


En función de lo que hice en el pasado cuando me enfrenté a problemas similares, sugeriría:

  • Escribe una transformación en XSLT a la que se consume el "filtro XML" y produce una transformación (también en XSLT).
  • Ejecute el XSLT resultante en su entrada.

Suena (y es) feo, pero he encontrado esto más fácil que tratar de interpretar la descripción del filtro sobre la marcha mientras se transforma la entrada.


Hmmm, estás hablando de fusión (suponiendo que tu documento de filtro sea variable). Hay un par de posibilidades que varían según el idioma en el que implemente todo esto. ¿Podría proporcionar más información sobre la aplicación?

De lo contrario, sugiero un google rápido en "xslt + merge" y ver si algún resultado allí te atrapa.