wake-up-neo.com

XSLT-Zeichenfolge ersetzen

Ich kenne XSL nicht wirklich, aber ich muss diesen Code korrigieren. Ich habe ihn reduziert, um ihn einfacher zu machen.
Ich erhalte diesen Fehler

Ungültige XSLT/XPath-Funktion

auf dieser Linie

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

Dies ist die 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>

Kann mir jemand sagen, was daran falsch ist?

82
Aximili

replace ist für XSLT 1.0 nicht verfügbar.

Codesling hat ein Template für string-replace das Sie als Ersatz für die Funktion verwenden können:

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

aufgerufen als:

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

Wenn Sie jedoch buchstäblich nur ein Zeichen durch ein anderes ersetzen müssen, können Sie translate aufrufen, das eine ähnliche Signatur hat. So etwas sollte gut funktionieren:

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

Beachten Sie auch, dass ich in diesem Beispiel den Variablennamen in "newtext" geändert habe. In XSLT sind Variablen unveränderlich, sodass Sie nicht das Äquivalent von $foo = $foo wie du es in deinem Originalcode getan hast.

133
Mark Elliot

Hier ist die XSLT-Funktion, die ähnlich wie die String.Replace () -Funktion von C # funktioniert.

Diese Vorlage hat die folgenden 3 Parameter

Text : - Ihre Hauptzeichenfolge

replace : - die Zeichenfolge, die Sie ersetzen möchten

von : - die Zeichenkette, die mit einer neuen Zeichenkette antwortet

Unten ist die Vorlage

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

Das folgende Beispiel zeigt, wie man es nennt

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

Sie können auch die nter URL für die Details beziehen.

36
Optimus

Hinweis: Wenn Sie den bereits erwähnten Algorithmus für Fälle verwenden möchten, in denen Sie eine große Anzahl von Instanzen in der Quellzeichenfolge ersetzen müssen (z. B. neue Zeilen im Langtext), gibt es hohe Wahrscheinlichkeit, dass Sie wegen des rekursiven Aufrufs mit StackOverflowException enden.

Ich habe dieses Problem gelöst, dank Xalan 's (nicht geschaut, wie es in Saxon) eingebauter Java Typ Einbettung :

<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>
12
Milan Aleksić

Sie können den folgenden Code verwenden, wenn Ihr Prozessor unter .NET ausgeführt wird oder MSXML verwendet (im Gegensatz zu Java-basierten oder anderen nativen Prozessoren). Es verwendet msxsl:script .

Stellen Sie sicher, dass Sie den Namespace xmlns:msxsl="urn:schemas-Microsoft-com:xslt" Zu Ihrem Root-Element xsl:stylesheet Oder xsl:transform Hinzufügen.

Binden Sie außerdem outlet an einen beliebigen Namespace, z. B. 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')" />
6
John Jin

Die Routine ist ziemlich gut, aber meine App hängt sich auf, so dass ich den Fall hinzufügen musste:

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

bevor die Funktion rekursiv aufgerufen wird.

Ich habe die Antwort von hier: Beim Test in einer Endlosschleife hängen

Vielen Dank!

0
Chesare