2013-01-11 22 views
5

में एक गतिशील मान-स्ट्रिंग से बचने वाला एकल उद्धरण मैं एक्सएसएलटी से जावास्क्रिप्ट चर परिभाषित कर रहा हूं और एक अनचाहे स्ट्रिंग के कारण त्रुटि प्राप्त कर रहा हूं। मैं समझता हूं कि मुझे इसे ' पर प्रतिस्थापित करने की आवश्यकता है, लेकिन मुझे यकीन नहीं है कि XSLT 1.0 में ऐसा कैसे करें।एक्सएसएलटी 1.0

XSLT उदाहरण:

var currentComment = '<xsl:value-of select="root/Reviews/Review/Comment" />'; 
नहीं छोड़ा जाएगा एकल उद्धरण के साथ

गाया जावास्क्रिप्ट:

var currentComment = 'Let's test a string.', 
// Causing an error ------^ 
+1

आप \ '' 'साथ बदलने के लिए' आवश्यकता होगी '',' ' '(और ई के साथ भी नहीं डबल बैकस्लैश के साथ बहुत बैकस्लैश) - आप जावास्क्रिप्ट पार्सर से बच रहे हैं, न कि HTML पार्सर। संभावित XSLT 1.0 समाधान के लिए [यह उत्तर] (http://stackoverflow.com/a/1069157/592139) पर एक नज़र डालें। –

उत्तर

7

के रूप में इयान रॉबर्ट्स उसकी टिप्पणी में बताया, तो आप बैकस्लैश के लिए खाते में और न कि केवल अक्षर लोप की जरूरत है। Dimitre के जवाब के रूप में इस के लिए खाते की इस प्रकार संशोधित किया जा सकता:

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

    <xsl:template match="/"> 
    <xsl:text>var currentComment = '</xsl:text> 
    <xsl:apply-templates select="root/value" mode="escape" /> 
    <xsl:text>'&#xA;</xsl:text> 

    <!-- Example with placing the escaped value in a variable first --> 
    <xsl:variable name="escapedOther"> 
     <xsl:apply-templates select="root/otherValue" mode="escape" /> 
    </xsl:variable> 
    <xsl:value-of select='concat("var otherComment = &apos;", $escapedOther, "&apos;")' /> 
    </xsl:template> 


    <xsl:template match="@* | node()" mode="escape"> 
    <!-- Escape the apostrophes second --> 
    <xsl:call-template name="replace"> 
     <xsl:with-param name="pTarget" select='"&apos;"' /> 
     <xsl:with-param name="pReplacement" select='"\&apos;"'/> 
     <xsl:with-param name="pText"> 
     <!-- Escape the backslashes first, and then pass that result directly into the next template --> 
     <xsl:call-template name="replace"> 
      <xsl:with-param name="pTarget" select="'\'" /> 
      <xsl:with-param name="pReplacement" select="'\\'" /> 
      <xsl:with-param name="pText" select="." /> 
     </xsl:call-template> 
     </xsl:with-param> 
    </xsl:call-template> 
    </xsl:template> 

    <xsl:template name="replace"> 
    <xsl:param name="pText"/> 
    <xsl:param name="pTarget" select='"&apos;"'/> 
    <xsl:param name="pReplacement" select="'\&quot;'"/> 

    <xsl:if test="$pText"> 
     <xsl:value-of select='substring-before(concat($pText,$pTarget),$pTarget)'/> 
     <xsl:if test='contains($pText, $pTarget)'> 
     <xsl:value-of select='$pReplacement'/> 
     </xsl:if> 

     <xsl:call-template name="replace"> 
     <xsl:with-param name="pText" select='substring-after($pText, $pTarget)'/> 
     <xsl:with-param name="pTarget" select="$pTarget"/> 
     <xsl:with-param name="pReplacement" select="$pReplacement"/> 
     </xsl:call-template> 
    </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

किसी भी समय आप कुछ से बचने के लिए की जरूरत है, तो आप सिर्फ apply-templates उस पर मोड escape साथ उपयोग कर सकते हैं। इस इनपुट XML के लिए:

<?xml version="1.0" encoding="utf-8"?> 
<root> 
    <value>Let's test a string that refers to something like the C:\ drive's \Program Files Directory.</value> 
    <otherValue>This value has a bunch of apostrophes '''' and backslashes \\\\ in it</otherValue> 
</root> 

यह पैदा करता है:

var currentComment = 'Let\'s test a string that refers to something like the C:\\ drive\'s \\Program Files Directory.' 
var otherComment = 'This value has a bunch of apostrophes \'\'\'\' and backslashes \\\\\\\\' 
+1

+1 मेरे कोड को "पुनः उपयोग करने" के लिए +1 :) –

3

यह परिवर्तन:

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

<xsl:variable name="vSomething">Let's test a string.</xsl:variable> 

<xsl:template match="/"> 
    <xsl:text>var currentComment = '</xsl:text> 
    <xsl:call-template name="replace"> 
    <xsl:with-param name="pText" select="$vSomething"/> 
    </xsl:call-template>' 
</xsl:template> 

<xsl:template name="replace"> 
    <xsl:param name="pText"/> 
    <xsl:param name="pTarget" select='"&apos;"'/> 
    <xsl:param name="pReplacement" select='"\&apos;"'/> 

    <xsl:if test="$pText"> 
    <xsl:value-of select='substring-before(concat($pText,$pTarget),$pTarget)'/> 
    <xsl:if test='contains($pText, $pTarget)'> 
    <xsl:value-of select="$pReplacement"/> 
    </xsl:if> 

    <xsl:call-template name="replace"> 
    <xsl:with-param name="pText" select='substring-after($pText, $pTarget)'/> 
    <xsl:with-param name="pTarget" select="$pTarget"/> 
    <xsl:with-param name="pReplacement" select="$pReplacement"/> 
    </xsl:call-template> 
    </xsl:if> 
</xsl:template> 
</xsl:stylesheet> 

जब किसी भी XML दस्तावेज़ पर लागू (इस्तेमाल नहीं किया), उत्पादन करता है चाहता था, सही परिणाम:

var currentComment = 'Let\'s test a string.' 
+0

आप 'प्रतिस्थापन' टेम्पलेट को गतिशील बनाने के इरादे से संभावित रूप से '$ pTarget' और '$ pReplacement' पैरामीटर को परिभाषित करने की समस्या पर गए हैं, लेकिन फिर आप वास्तव में उन चीज़ों का उपयोग नहीं करते हैं जहां यह महत्वपूर्ण है। – JLRishe

+0

@JLRishe, हां, यह * डिज़ाइन द्वारा * है :) ध्यान दें कि मैंने इन पैरामीटर को उपयुक्त * डिफ़ॉल्ट मान * दिए हैं। तो, परिणाम यह है कि मैं उन्हें इस विशेष मामले में टेम्पलेट के बाहरी कॉल में छोड़ सकता हूं। –

+0

मैं उन्हें टेम्पलेट कॉल से छोड़ने का जिक्र नहीं कर रहा हूं - मैं इन पंक्तियों में उनका उपयोग न करने का जिक्र कर रहा हूं: ' ',' \' ',' '। अगर कोई वास्तव में उन मानकों के मानों में गुजरता था, तो यह अभी भी '' '->' \ ''प्रतिस्थापन करेगा। – JLRishe

0

यह सिर्फ JLRische-Novachev समाधान मैं अपने एक्सएमएल पूरा करने के लिए किया था के एक कार्यान्वयन है। शायद यह उपयोगी हो सकता है:

<?xml version="1.0" encoding="utf-8"?> 
<root> 
    <value msg="1- Let's test a string that refers to something like the C:\ drive's \Program  Files Directory." num="1"/> 
    <value msg="2- Let's test a string that refers to something like the C:\ drive's \Program Files Directory." num="2"/> 
</root> 

XSL:

... 
<xsl:template match="@* | node()" mode="escape"> 

    <!-- Escape the apostrophes second --> 
    <xsl:call-template name="replace"> 
     <xsl:with-param name="pTarget" select='"&apos;"' /> 
     <xsl:with-param name="pReplacement" select='"\&apos;"'/> 
     <xsl:with-param name="pText"> 
     <!-- Escape the backslashes first, and then pass that result directly into the next  template --> 
     <xsl:call-template name="replace"> 
      <xsl:with-param name="pTarget" select="'\'" /> 
      <xsl:with-param name="pReplacement" select="'\\'" /> 
      <xsl:with-param name="pText" select="./@msg" /> 
     </xsl:call-template> 
     </xsl:with-param> 
    </xsl:call-template> 

<xsl:text>, Number: </xsl:text><xsl:value-of select="./@num"/><xsl:text>&#xA;</xsl:text> 

... 

आउटपुट:

1- Let\'s test a string that refers to something like the C:\\ drive\'s \\Program Files Directory., Number: 1 
2- Let\'s test a string that refers to something like the C:\\ drive\'s \\Program Files Directory., Number: 2 
संबंधित मुद्दे