Pregunta XSLT string replace


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?


74
2018-06-18 03:54


origen


Respuestas:


replace no está disponible para XSLT 1.0.

Codesling tiene un Plantilla para reemplazar cadena puedes usarlo 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 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 "texto nuevo", en XSLT las variables son inmutables, por lo que no puede hacer el equivalente de $foo = $foo como tenías en tu código original.


127
2018-06-18 03:58



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 : - tu cuerda 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 recomendar debajo de la URL para los detalles.


33
2018-05-10 06:58



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 fuente (por ejemplo, nuevas líneas en texto largo), existe alto probabilidad de que termines con StackOverflowException debido a la llamada recursiva.

Resolví este problema gracias a Xalan's (no parecía cómo hacerlo en sajón) incrustación incorporada de tipo Java:

<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>

11
2017-09-11 07:37



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). Usa msxsl:script.

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

Además, ata outlet a cualquier espacio de nombre que desee, 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')" />

5
2018-03-28 00:35



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.

Tengo la respuesta de aquí: Cuando la prueba cuelga en un ciclo infinito

¡Gracias!


0
2018-01-08 20:15