2012-12-20 13 views
14

फ़ंक्शन normalize-space एक स्थान से व्हाइटस्पेस के अनुक्रमों को प्रतिस्थापित करता है और प्रदान की गई स्ट्रिंग को ट्रिम करता है। मैं व्हाइटस्पेस के प्रतिस्थापन के बिना केवल स्ट्रिंग को कैसे ट्रिम कर सकता हूं? orcl:left-trim जैसे स्वामित्व समाधान हैं, लेकिन मैं एक गैर-स्वामित्व वाले व्यक्ति की तलाश में हूं।मैं XSLT में स्पेसिंग व्हाइटस्पेस को प्रतिस्थापित किए बिना स्थान को कैसे ट्रिम कर सकता हूं?

उदाहरण:

<xsl:value-of select="trim(/Car/Description)"/> 

कर देना चाहिए

<car> 
    <description> To get more information look at:  www.example.com </description> 
</car> 

में

"To get more information look at:  www.example.com" 

उत्तर

16

केवल xslt 1 का उपयोग कर एक समाधान।0 टेम्पलेट्स:

<xsl:variable name="whitespace" select="'&#09;&#10;&#13; '" /> 

<!-- Strips trailing whitespace characters from 'string' --> 
<xsl:template name="string-rtrim"> 
    <xsl:param name="string" /> 
    <xsl:param name="trim" select="$whitespace" /> 

    <xsl:variable name="length" select="string-length($string)" /> 

    <xsl:if test="$length &gt; 0"> 
     <xsl:choose> 
      <xsl:when test="contains($trim, substring($string, $length, 1))"> 
       <xsl:call-template name="string-rtrim"> 
        <xsl:with-param name="string" select="substring($string, 1, $length - 1)" /> 
        <xsl:with-param name="trim" select="$trim" /> 
       </xsl:call-template> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:value-of select="$string" /> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:if> 
</xsl:template> 

<!-- Strips leading whitespace characters from 'string' --> 
<xsl:template name="string-ltrim"> 
    <xsl:param name="string" /> 
    <xsl:param name="trim" select="$whitespace" /> 

    <xsl:if test="string-length($string) &gt; 0"> 
     <xsl:choose> 
      <xsl:when test="contains($trim, substring($string, 1, 1))"> 
       <xsl:call-template name="string-ltrim"> 
        <xsl:with-param name="string" select="substring($string, 2)" /> 
        <xsl:with-param name="trim" select="$trim" /> 
       </xsl:call-template> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:value-of select="$string" /> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:if> 
</xsl:template> 

<!-- Strips leading and trailing whitespace characters from 'string' --> 
<xsl:template name="string-trim"> 
    <xsl:param name="string" /> 
    <xsl:param name="trim" select="$whitespace" /> 
    <xsl:call-template name="string-rtrim"> 
     <xsl:with-param name="string"> 
      <xsl:call-template name="string-ltrim"> 
       <xsl:with-param name="string" select="$string" /> 
       <xsl:with-param name="trim" select="$trim" /> 
      </xsl:call-template> 
     </xsl:with-param> 
     <xsl:with-param name="trim" select="$trim" /> 
    </xsl:call-template> 
</xsl:template> 

टेस्ट कोड:

<ltrim> 
    <xsl:call-template name="string-ltrim"> 
     <xsl:with-param name="string" select="' &#10; test '" /> 
    </xsl:call-template> 
</ltrim> 
<rtrim> 
    <xsl:call-template name="string-rtrim"> 
     <xsl:with-param name="string" select="' &#10; test &#10; '" /> 
    </xsl:call-template> 
</rtrim> 
<trim> 
    <xsl:call-template name="string-trim"> 
     <xsl:with-param name="string" select="' &#10; test &#10; '" /> 
    </xsl:call-template> 
</trim> 

आउटपुट:

<test> 
    <ltrim>test </ltrim> 
    <rtrim> 
    test</rtrim> 
    <trim>test</trim> 
</test> 
+0

मुझे अतिरिक्त पुस्तकालयों को जोड़ने के साफ समाधान पसंद हैं - इस के लिए धन्यवाद! चूंकि मुझे पहले प्रोजेक्ट मैनेजर से पूछना होगा, चाहे हम अतिरिक्त पुस्तकालय जोड़ सकें, यह समाधान मेरे लिए स्पष्ट रूप से बेहतर है। मुझे लगता है कि xsl-file की शुरुआत में एक पैरामीटर डालने का कोई तरीका नहीं है ताकि सभी फ़ील्ड छंटनी हो सकें, है ना? मुझे '' मिला, लेकिन यह केवल 'concat (...)' जैसे अन्य परिवर्तनों के बाद लागू होता है, जिसके परिणामस्वरूप 'अंतिम नाम, प्रथम नाम' के बजाय 'अंतिम नाम, प्रथम नाम' जैसे परिणाम होते हैं। ऐसा लगता है कि ऐसा कोई आसान समाधान नहीं है ... –

+2

@MathiasBader: 'xsl: स्ट्रिप-स्पेस 'किसी भी रूपांतरण से पहले, स्रोत दस्तावेज़ पर काम करता है, और टेक्स्ट नोड्स को हटा देता है जिसमें केवल व्हाइटस्पेस होता है। यह शायद आपकी समस्या का समाधान नहीं करेगा। सबसे आसान समाधान शायद एक अलग परिवर्तन बनाने के लिए होगा जो केवल चयनित तत्वों की सफेद जगहों को ट्रिम्स करेगा, और दूसरे रूपांतरण के लिए इनपुट के रूप में इसके परिणाम का उपयोग करेगा। यह एक विशिष्ट प्रोसेसर के लिए एक्सटेंशन फ़ंक्शंस का उपयोग करके, या ट्रांसफॉर्मेशन का आह्वान करने के लिए बाहरी टूल/एपीआई का उपयोग करके एकल स्टाइलशीट में किया जा सकता है। –

+0

बाहरी उपकरण द्वारा एक अलग (पूर्व-) परिवर्तन का उपयोग करना कुछ ऐसा था जो मुझे भी दिमाग में था। मैंने सोचा कि समस्या सामान्य है, मैंने सोचा कि एक्सएसएलटी द्वारा प्रदान किया गया एक आसान समाधान होना चाहिए जो मुझे अभी तक नहीं मिला है। –

2

XSLT कार्यात्मक प्रोग्रामिंग के लिए FXSL (खुला स्रोत पुस्तकालय का उपयोग करना, XSL में पूरी तरह से लिखा टी) एक बस लिखते:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:import href="trim.xsl"/> 

    <xsl:output method="text"/> 
    <xsl:template match="/*/description"> 
    '<xsl:call-template name="trim"> 
     <xsl:with-param name="pStr" select="."/> 
    </xsl:call-template>' 
    </xsl:template> 
</xsl:stylesheet> 

जब इस बदलाव प्रदान की XML दस्तावेज़ पर भी लागू होता है:

<car> 
    <description> To get more information look at:  www.example.com </description> 
</car> 

चाहता था, सही परिणाम का उत्पादन किया है:

'To get more information look at:  www.example.com' 

trim टेम्पलेट कैसे काम करता है?

यह बाएं अग्रणी व्हाइटस्पेस को ट्रिम करता है, फिर यह परिणामी स्ट्रिंग को उलट देता है और इसके अग्रणी व्हाइटस्पेस को ट्रिम करता है, फिर अंततः परिणामी स्ट्रिंग को उलट देता है।


II। XPath 2.0 समाधान:

उपयोग: - 2.0 -

replace(replace(/*/description, '^\s*(.+?)\s*$', '$1'), '^ .*$', '') 

यहाँ एक XSLT है आधारित सत्यापन:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/"> 
    "<xsl:sequence 
     select="replace(replace(/*/description, '^\s*(.+?)\s*$', '$1'), '^ .*$', '')"/>" 
</xsl:template> 
</xsl:stylesheet> 

जब इस बदलाव प्रदान की XML दस्तावेज़ पर लागू किया जाता है (ऊपर), XPath अभिव्यक्ति का मूल्यांकन किया जाता है और इस मूल्यांकन का परिणाम आउटपुट में कॉपी किया जाता है:

"To get more information look at:  www.example.com" 
+0

अपने जवाब यह है कि एक अच्छा समाधान की तरह लगता है के लिए धन्यवाद। क्या मैं सही हूं कि कोई 'मूल' समाधान नहीं है जिसके लिए अतिरिक्त पुस्तकालय की आवश्यकता नहीं होगी (जो, ज़ाहिर है, अतिरिक्त पुस्तकालय आयात करने के लिए बेहतर होगा)? –

+0

@MathiasBader, सबसे पहले, FXSL * का उपयोग * एक देशी समाधान है - FXSL XSLT टेम्पलेट्स का एक सेट है। यदि आप एफएक्सएसएल का उपयोग नहीं करना चाहते हैं, तो कोई एक रिकर्सिव एक्सएसएलटी समाधान लिख सकता है - ऐसा करने के लिए केवल बुद्धिमान नहीं है जब कोई पहले से ही मौजूदा (और परीक्षण) FXSL समाधान को कॉल कर सकता है। यदि आप कुछ घंटों, या अतिरिक्त काम के एक दिन को सहेजना नहीं चाहते हैं, और यह सुनिश्चित करने के लिए कि समाधान में कोई बग नहीं है, तो स्क्रैच से एक रूपांतरण लिखें। एफएक्सएसएल का उद्देश्य उन समस्याओं के समाधान लिखने के प्रयास को कम करना है जो बहुत मुश्किल हैं या "लगभग असंभव" हैं। –

+0

@MathiasBader, इसे दूसरे शब्दों में रखने के लिए, इस उत्तर के साथ मैं चाहता हूं: 1. आपको बहुत समय और विकास/सत्यापन प्रयास बचाने के लिए। 2. आपको यह बताने के लिए कि एक उपकरण मौजूद है जो अधिकांश कार्यों के लिए आपके एक्सएसएलटी विकास समय को नाटकीय रूप से कम कर सकता है और उन कार्यों को बना सकता है जो अनिवार्य रूप से कठिन ("लगभग असंभव") एक्सएसएलटी के साथ काफी प्राकृतिक और सीधा है। –

-2

आप बीच में कोई खाली स्थान नहीं है, तो आप बस का उपयोग कर सकते हैं:

translate(/Car/Description,' ','') 
+0

अच्छा विचार है, लेकिन जैसा कि आपने पहले ही अनुमान लगाया होगा, दुर्भाग्य से यह एक सरलीकरण का बहुत अधिक है। –

2

सामान्यीकृत-स्थान (वास्तविक सेटिंग) - यह ऐसा करेगा।

+0

यह बीच में दोहराने वाली सफेद जगहों को भी हटा देगा। मैं ऐसे समाधान की तलाश में था जो ऐसा नहीं करता है। –

3

एक XSLT1 साथ बहुत ही कम समाधान:

<xsl:template name="trim"> 
      <xsl:param name="str"/> 

      <xsl:choose> 
       <xsl:when test="string-length($str) &gt; 0 and substring($str, 1, 1) = ' '"> 
        <xsl:call-template name="trim"><xsl:with-param name="str"><xsl:value-of select="substring($str, 2)"/></xsl:with-param></xsl:call-template></xsl:when> 
       <xsl:when test="string-length($str) &gt; 0 and substring($str, string-length($str)) = ' '"> 
        <xsl:call-template name="trim"><xsl:with-param name="str"><xsl:value-of select="substring($str, 1, string-length($str)-1)"/></xsl:with-param></xsl:call-template></xsl:when> 
       <xsl:otherwise><xsl:value-of select="$str"/></xsl:otherwise> 
      </xsl:choose> 
     </xsl:template> 
संबंधित मुद्दे

 संबंधित मुद्दे