xsl variable example create xslt

xslt - example - Cómo usar la variable XSL en xsl: apply-templates?



xslt introduction (6)

Tengo una llamada bastante compleja a xsl: apply-templates:

<xsl:apply-templates select="columnval[@id and not(@id=''_Name_'') and not(@id=''Group'') and not(@id=''_Count_'')]"/>

La expresión se reutiliza en otros lugares como este:

<xsl:apply-templates select="someothernode[@id and not(@id=''_Name_'') and not(@id=''Group'') and not(@id=''_Count_'')]"/>

Quiero generalizarlo de alguna manera, así que puedo definirlo una vez y reutilizarlo en otro lugar. Sin embargo, esto no parece funcionar:

<xsl:variable name="x">@id and not(@id=''_Name_'') and not(@id=''Group'') and not(@id=''_Count_'')</xsl:variable> <xsl:apply-templates select="columnval[$x]"/> <xsl:apply-templates select="someothernode[$x]"/>

¿Hay una manera mejor / diferente de hacer esto? Todo lo que quiero es reutilizar la expresión xpath en múltiples llamadas diferentes a xsl: apply-templates (algunas de las cuales seleccionan de diferentes hijos).

Esto se usará en una aplicación cliente, por lo que no puedo utilizar ninguna extensión o cambiar a XSLT 2 por desgracia. :(

Gracias.


Con la extensión exsl: nodeset, puede crear una plantilla con nombre que acepte un conjunto de nodos $ x y devuelva el conjunto de nodos filtrado de acuerdo con su predicado estático.

También puede definir una función en XSLT 2.0.



No puede construir XPath dinámicamente en XSLT (al menos, no XSLT 1.0). Pero puedes lograr fácilmente lo que intentas hacer usando los modos de plantilla:

<xsl:apply-templates select="columnval" mode="filter"/> <xsl:apply-template select="someothernode" mode="filter"/> ... <!-- this guarantees that elements that don''t match the filter don''t get output --> <xsl:template match="*" mode="filter"/> <xsl:template match="*[@id and not(@id=''_Name_'') and not(@id=''Group'') and not(@id=''_Count_'')]" mode="filter"> <xsl:apply-templates select="." mode="filtered"/> </xsl:template> <xsl:template match="columnval" mode="filtered"> <!-- this will only be applied to the columnval elements that pass the filter --> </xsl:template> <xsl:template match="someothernode" mode="filtered"> <!-- this will only be applied to the someothernode elements that pass the filter --> </xsl:template>


Qué tal si:

<xsl:variable name="filter" select="_Name_|Group|_Count_" /> <xsl:apply-templates select="columnval" mode="filtered" /> <xsl:apply-templates select="someothernode" mode="filtered" /> <xsl:template match="someothernode|columnval" mode="filtered"> <xsl:if test="not(contains( concat(''|'', $filter,''|''), concat(''|'', @id,''|''), ))"> <!-- whatever --> </xsl:if> </xsl:template>

Podrías hacer $filter un param, y pasarlo desde el exterior, por ejemplo.

Lo que no puedes hacer (como habrás notado) es utilizar variables para almacenar expresiones XPath.


Refactorizando @Robert Rossney y @Tomalak

<xsl:apply-templates select="columnval" mode="filter"/> <xsl:apply-templates select="someothernode" mode="filter"/> <xsl:template match="*" mode="filter"> <xsl:param name="pFilter" select="''_Name_|Group|_Count_''"/> <xsl:apply-templates select="self::* [not(contains( concat(''|'',$pFilter,''|''), concat(''|'',@id,''|''))) and @id]"/> </xsl:template>


XSLT 1.0 y XSLT 2.0 no son compatibles con la evaluación dinámica.

Una forma de hacerlo es usar <xsl:function> en XSLT 2.0 o <xsl:call-template> en XSLT 1.0 .

<xsl:function name="my:test" as="xs:boolean"> <xsl:param name="pNode" as="element()"/> <xsl:variable name="vid" select="$pNode/@id"/> <xsl:sequence select= "$vid and not($vid=(''_Name_'',''Group'',''_Count_'')"/> </xsl:function>

entonces podrías usar esta función :

<xsl:apply-templates select="columnval[my:test(.)]"/>

Ciertamente, podría especificar la prueba en patrones de coincidencia específicos según lo sugerido por Robert Rossney , y esta podría ser la mejor manera.

En caso de que necesite definir dinámicamente qué función de filtrado utilizar, una poderosa herramienta es la biblioteca FXSL , que implementa funciones de orden superior (HOF) en XSLT. HOF son funciones que aceptan otras funciones como parámetros y pueden devolver una función como resultado.

Usando este enfoque, usted determina dinámicamente y pasa a my:test() como parámetro una función que hace la prueba.