[xslt] XSLT 문자열 교체

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에는 함수 대신 사용할 수있는 문자열 교체 템플릿 이 있습니다.

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

반면에 문자 그대로 한 문자 만 다른 문자로 바꾸면 translate되는 경우 유사한 서명을 가진 호출 할 수 있습니다 . 다음과 같은 것이 잘 작동합니다.

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

또한이 예에서는 변수 이름을 “newtext”로 변경했습니다. XSLT 변수는 변경 불가능하므로 $foo = $foo원래 코드에서와 동일한 작업을 수행 할 수 없습니다 .


답변

다음은 C #의 String.Replace () 함수와 유사하게 작동하는 XSLT 함수입니다.

이 템플릿에는 아래와 같이 3 개의 매개 변수가 있습니다.

텍스트 :-기본 문자열

교체 :- 교체 하려는 문자열

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>

자세한 내용은 아래 URL 을 참조 하십시오.


답변

참고 : 소스 문자열에서 많은 수의 인스턴스를 교체해야하는 경우 (예 : 긴 텍스트의 새 줄) 이미 언급 한 알고리즘을 사용하려는 경우 재귀 로 인해 끝날 가능성 이 높습니다.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')" />


답변

나는이 대답을 계속칩니다. 그러나 그들 중 어느 것도 xsltproc (그리고 아마도 대부분의 XSLT 1.0 프로세서)에 대한 가장 쉬운 솔루션을 나열하지 않습니다.

  1. exslt 문자열 이름을 스타일 시트에 추가합니다.
<xsl:stylesheet
  version="1.0"
  xmlns:str="http://exslt.org/strings"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  1. 그런 다음 다음과 같이 사용하십시오.
<xsl:value-of select="str:replace(., ' ', '')"/>


답변

루틴은 꽤 좋지만 앱이 중단되므로 케이스를 추가해야합니다.

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

함수가 재귀 적으로 호출되기 전에.

나는 여기에서 답을 얻었습니다 :
무한 루프에서 테스트가 걸려있을 때

감사합니다!


답변