私は実際にはXSLを知りませんが、このコードを修正する必要があります。より簡単にするためにそれを減らしました。
このエラーが発生しています
無効なXSLT/XPath関数
この行に
<xsl:variable name="text" select="replace($text,'a','b')"/>
これが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>
誰がそれが間違っているのか教えてもらえますか?
replace
はXSLT 1.0では使用できません。
Codeslingには string-replaceのテンプレート があり、関数の代替として使用できます。
<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>
として呼び出される:
<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>
一方、文字どおりに1つの文字を別の文字に置き換えるだけの場合は、同様のシグネチャを持つ translate
を呼び出すことができます。このような何かがうまくいくはずです:
<xsl:variable name="newtext" select="translate($text,'a','b')"/>
また、この例では、変数名を「newtext」に変更したことに注意してください。XSLT変数は不変であるため、元のコードにあったような$foo = $foo
に相当することはできません。
C#のString.Replace()関数と同様に機能するXSLT関数を次に示します。
このテンプレートには、以下の3つのパラメーターがあります
text:-メイン文字列
replace:-置換したい文字列
by:-新しい文字列で応答する文字列
以下がテンプレートです
<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>
以下のサンプルは、それを呼び出す方法を示しています
<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>
詳細については、 RLの下 を参照することもできます。
注:ソース文字列の膨大な数のインスタンス(長いテキストの改行など)を置き換える必要がある場合に前述のアルゴリズムを使用する場合は、high再帰呼び出しのためにStackOverflowException
になる確率。
Xalanのおかげでこの問題を解決しました(Saxonでそれを行う方法を見ていませんでした)組み込み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>
プロセッサが.NETで実行される場合、またはMSXMLを使用する場合(Javaベースまたはその他のネイティブプロセッサとは対照的に)、次のコードを使用できます。 msxsl:script
を使用します。
ルートxmlns:msxsl="urn:schemas-Microsoft-com:xslt"
またはxsl:stylesheet
要素に名前空間xsl:transform
を追加してください。
さらに、outlet
を任意のネームスペース、たとえば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')" />
ルーチンはかなり良いですが、それは私のアプリをハングアップさせるので、ケースを追加する必要がありました:
<xsl:when test="$text = '' or $replace = ''or not($replace)" >
<xsl:value-of select="$text" />
<!-- Prevent thsi routine from hanging -->
</xsl:when>
関数が再帰的に呼び出される前。
私はここから答えを得ました: テストが無限ループにぶら下がっているとき
ありがとうございました!