what xslt xpath replace xslt-1.0 xpath-1.0

what - XSLT string replace



what is xml (5)

Realmente no conozco XSL pero necesito corregir este código, lo he reducido para hacerlo más simple.
Estoy recibiendo este error

Función XSLT / XPath inválida

en esta linea

<xsl:variable name="text" select="replace($text,''a'',''b'')"/>

Este es el XSL

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:inm="http://www.inmagic.com/webpublisher/query" version="1.0"> <xsl:output method="text" encoding="UTF-8" /> <xsl:preserve-space elements="*" /> <xsl:template match="text()" /> <xsl:template match="mos"> <xsl:apply-templates /> <xsl:for-each select="mosObj"> ''Notes or subject'' <xsl:call-template name="rem-html"> <xsl:with-param name="text" select="SBS_ABSTRACT" /> </xsl:call-template> </xsl:for-each> </xsl:template> <xsl:template name="rem-html"> <xsl:param name="text" /> <xsl:variable name="text" select="replace($text, ''a'', ''b'')" /> </xsl:template> </xsl:stylesheet>

¿Alguien puede decirme qué pasa con eso?


Aquí está la función XSLT que funcionará de forma similar a la función String.Replace () de C #.

Esta plantilla tiene los 3 parámetros como abajo

texto : su cadena principal

reemplazar : - la cadena que desea reemplazar

por : - la cadena que responderá por una nueva cadena

A continuación están la plantilla

<xsl:template name="string-replace-all"> <xsl:param name="text" /> <xsl:param name="replace" /> <xsl:param name="by" /> <xsl:choose> <xsl:when test="contains($text, $replace)"> <xsl:value-of select="substring-before($text,$replace)" /> <xsl:value-of select="$by" /> <xsl:call-template name="string-replace-all"> <xsl:with-param name="text" select="substring-after($text,$replace)" /> <xsl:with-param name="replace" select="$replace" /> <xsl:with-param name="by" select="$by" /> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$text" /> </xsl:otherwise> </xsl:choose> </xsl:template>

La muestra siguiente muestra cómo llamarlo

<xsl:variable name="myVariable "> <xsl:call-template name="string-replace-all"> <xsl:with-param name="text" select="''This is a {old} text''" /> <xsl:with-param name="replace" select="''{old}''" /> <xsl:with-param name="by" select="''New''" /> </xsl:call-template> </xsl:variable>

También puede consultar la siguiente URL para conocer los detalles.


La rouine es bastante buena, sin embargo hace que mi aplicación se cuelgue, así que necesitaba agregar la funda:

<xsl:when test="$text = '''' or $replace = ''''or not($replace)" > <xsl:value-of select="$text" /> <!-- Prevent thsi routine from hanging --> </xsl:when>

antes de que la función sea llamada recursivamente.

Obtuve la respuesta de aquí: cuando la prueba colgaba en un ciclo infinito

¡Gracias!


Puede usar el siguiente código cuando su procesador se ejecuta en .NET o usa MSXML (a diferencia de los procesadores nativos basados ​​en Java u otros). Utiliza msxsl:script .

Asegúrese de agregar el espacio de nombres xmlns:msxsl="urn:schemas-microsoft-com:xslt" a su raíz xsl:stylesheet o xsl:transform element.

Además, vincula la outlet a cualquier espacio de nombre que desees, por ejemplo xmlns:outlet = "http://my.functions" .

<msxsl:script implements-prefix="outlet" language="javascript"> function replace_str(str_text,str_replace,str_by) { return str_text.replace(str_replace,str_by); } </msxsl:script> <xsl:variable name="newtext" select="outlet:replace_str(string(@oldstring),''me'',''you'')" />


replace no está disponible para XSLT 1.0.

Codesling tiene una plantilla para reemplazar cadena que puede usar como sustituto de la función:

<xsl:template name="string-replace-all"> <xsl:param name="text" /> <xsl:param name="replace" /> <xsl:param name="by" /> <xsl:choose> <xsl:when test="$text = '''' or $replace = ''''or not($replace)" > <!-- Prevent this routine from hanging --> <xsl:value-of select="$text" /> </xsl:when> <xsl:when test="contains($text, $replace)"> <xsl:value-of select="substring-before($text,$replace)" /> <xsl:value-of select="$by" /> <xsl:call-template name="string-replace-all"> <xsl:with-param name="text" select="substring-after($text,$replace)" /> <xsl:with-param name="replace" select="$replace" /> <xsl:with-param name="by" select="$by" /> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$text" /> </xsl:otherwise> </xsl:choose> </xsl:template>

invocado como:

<xsl:variable name="newtext"> <xsl:call-template name="string-replace-all"> <xsl:with-param name="text" select="$text" /> <xsl:with-param name="replace" select="a" /> <xsl:with-param name="by" select="b" /> </xsl:call-template> </xsl:variable>

Por otro lado, si literalmente solo necesitas reemplazar un personaje por otro, puedes llamar a translate que tiene una firma similar. Algo así debería funcionar bien:

<xsl:variable name="newtext" select="translate($text,''a'',''b'')"/>

Además, tenga en cuenta que, en este ejemplo, cambié el nombre de la variable a "newtext", en XSLT las variables son inmutables, por lo que no puede hacer el equivalente de $foo = $foo como lo hizo en su código original.


Nota: En caso de que desee utilizar el algoritmo ya mencionado para casos en los que necesite reemplazar un gran número de instancias en la cadena de origen (por ejemplo, nuevas líneas en texto largo), es muy probable que termine con Exception debido a la llamada recursiva

Resolví este problema gracias a la incrustación incorporada de Xalan (no se veía cómo hacerlo en Saxon ):

<xsl:stylesheet version="1.0" exclude-result-prefixes="xalan str" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xalan" xmlns:str="xalan://java.lang.String" > ... <xsl:value-of select="str:replaceAll( str:new(text()), $search_string, $replace_string)"/> ... </xsl:stylesheet>