XSLT स्ट्रिंग की जगह


85

मुझे वास्तव में 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()फ़ंक्शन XPath 2.0 (और इसलिए XSLT 2.0) से उपलब्ध है और बाद में नियमित अभिव्यक्ति प्रतिस्थापन का समर्थन करता है।
हाबिल

जवाबों:


147

replace XSLT 1.0 के लिए उपलब्ध नहीं है।

कोडिंग में स्ट्रिंग के लिए एक टेम्प्लेट है, जिसे आप फ़ंक्शन के विकल्प के रूप में उपयोग कर सकते हैं:

<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अपने मूल कोड में जैसा था वैसा नहीं कर सकते ।


धन्यवाद मार्क, लेकिन अब मुझे यह त्रुटि मिल रही है: अज्ञात XPath एक्सटेंशन फ़ंक्शन को कॉल किया गया था
Aximili

@aximili, क्षमा करें, XSLT 1.0 और 2.0 को भ्रमित किया गया, संपादित किया गया ... अब जाने के लिए अच्छा होना चाहिए।
मार्क इलियट

19
यह उत्तर गलत है! XSLT में प्रतिस्थापित फ़ंक्शन एकल वर्णक्रमों की जगह लेता है, पूरे तार नहीं! उदाहरण के लिए यहाँ देखें: w3schools.com/xpath/xpath_functions.asp
जैकब

12
@ जैकब आप सोच रहे हैं translate, नहीं replacereplaceXPath में समारोह एक के रूप में अपनी दूसरा तर्क 2.0 व्यवहार करता है नियमित अभिव्यक्ति और बदलने वाला निर्दिष्ट प्रतिस्थापन स्ट्रिंग (जो शामिल हो सकते हैं के साथ कि अभिव्यक्ति की सभी मैचों $nregex में कब्जा समूहों के लिए संदर्भ)। translateसमारोह (1.0 और 2.0 में) एक ही है कि एकल चरित्र के लिए एकल चरित्र प्रतिस्थापन करता है।
इयान रॉबर्ट्स

6
उदाहरण के उपयोग में 4th लाइन <xsl:with-param name="replace" select="'a'" />a के आसपास के कोट्स के साथ नहीं होनी चाहिए ?
डीजेएल

37

यहाँ XSLT फ़ंक्शन है जो String.Replace () C # के फ़ंक्शन के समान काम करेगा।

इस टेम्पलेट में नीचे के रूप में 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 को भी देख सकते हैं ।


1
Xslt 1.0 का उपयोग करते हुए मार्क इलियट ने ऐसा नहीं किया, जबकि इस पोस्ट / टेम्पलेट ने मेरे लिए काम किया।
HostMyBus

12

नोट: यदि आप उन मामलों के लिए पहले से उल्लेख किए गए एल्गो का उपयोग करना चाहते हैं, जहां आपको स्रोत स्ट्रिंग में बड़ी संख्या में उदाहरणों को बदलने की आवश्यकता है (उदाहरण के लिए लंबे पाठ में नई लाइनें) तो उच्च संभावना है कि आप 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>

क्षमा करें यदि मैं गूंगा हो रहा हूं, लेकिन मुझे मिलता है:Cannot find a script or an extension object associated with namespace 'xalan://java.lang.String'.
इयान ग्रिंगर

आपका XSLT इंजन क्या है?
मिलान अलेक्सिएक

3
मेरी टिप्पणी सबसे लोकप्रिय जावा XSLT 1.0 इंजन Xalan ( xml.apache.org/xalan-j ) के लिए थी, जो उपलब्ध जावा वर्गपथ के अंदर उपलब्ध प्रकारों के लिए प्रत्यक्ष मानचित्रण का समर्थन करता है; आप .Net स्टैक के लिए मेरे समाधान को लागू नहीं कर सकते
मिलान अलेक्सिएक

@IanGrainger, आप इसे एक <msxsl:script>ब्लॉक जोड़कर .NET के साथ उपयोग कर सकते हैं , जिसे कोई भी .NET विधि, लाइब्रेरी आदि कह सकते हैं। हालाँकि .NET EXSLT एक्सटेंशन फ़ंक्शन का भी समर्थन करता है, इसलिए आपको इसकी आवश्यकता नहीं होगी।
हाबिल

exslt भी समर्थित है libxslt और इसलिए सभी वंशजों में xsltproc आदि ...
एलेन Pannetier

7

आप निम्न कोड का उपयोग कर सकते हैं जब आपका प्रोसेसर .NET पर चलता है या MSXML का उपयोग करता है (जैसा कि जावा-आधारित या अन्य मूल प्रोसेसर के विपरीत)। इसका उपयोग करता है 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')" />

क्षमा करें यदि मैं गूंगा हो रहा हूं, लेकिन मुझे मिलता है prefix outlet is not definedया 'xsl:script' cannot be a child of the 'xsl:stylesheet' element.यदि मैं अपने उपसर्ग के लिए msxsl बदलता हूं। मुझे लगता है कि यह कुछ Microsoft-विशिष्ट XSLT जादू है?
इयान ग्रिंगर

1
@IanGrainger, यह नहीं है xsl:script, लेकिन msxsl:script, और इसका अलग नाम है (मैंने जॉन का जवाब अपडेट किया है)।
हाबिल

1

मैं इस जवाब को दबाए रखता हूं। लेकिन उनमें से कोई भी 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(., ' ', '')"/>

1
मेरे कंप्यूटर पर xsltproc (macOS 10.13) str:replace()फ़ंक्शन का समर्थन नहीं करता है। न ही किसी अन्य प्रमुख XSLT 1.0 प्रोसेसर - Xalan, Saxon 6.5 और Microsoft।
michael.hor257k

0

रूटीन बहुत अच्छा है, हालांकि इससे मेरा ऐप लटका हुआ है, इसलिए मुझे मामला जोड़ने की जरूरत है:

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

इससे पहले कि फ़ंक्शन को पुनरावर्ती कहा जाता है।

मुझे यहां से जवाब मिला: जब परीक्षण एक अनंत लूप में लटका हुआ है

धन्यवाद!

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.