2013-01-11 3 views
5

Ich definiere eine JavaScript-Variable aus XSLT und erhalte einen Fehler aufgrund einer nicht-restringierten Zeichenfolge. Ich verstehe, dass ich dies zu ' ersetzen muss, aber ich bin mir nicht sicher, wie man das in XSLT 1.0 macht.Einfaches Anführungszeichen, das einem dynamischen Wert von Zeichenfolge in XSLT 1.0 entgeht

XSLT-Beispiel:

var currentComment = '<xsl:value-of select="root/Reviews/Review/Comment" />'; 

Rendered Javascript mit unescaped Apostroph:

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

Sie müssen die ' 'ersetzen' mit '\ ''nicht mit' ' '(und auch e sehr Backslash mit Doppel-Backslash) - Sie entkommen es vom JavaScript-Parser, nicht vom HTML-Parser. Werfen Sie einen Blick auf [diese Antwort] (http://stackoverflow.com/a/1069157/592139) für eine mögliche XSLT 1.0-Lösung. –

Antwort

7

Als Ian Roberts in seinem Kommentar darauf hingewiesen, müssen Sie Schrägstriche berücksichtigen und nicht nur Apostrophe. Dimitre Antwort kann modifiziert werden, wie dies zu berücksichtigen folgt:

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

Jedes Mal, wenn etwas entkommen müssen, die Sie gerade apply-templates auf sie mit dem Modus escape verwenden können. Für diesen Eingang 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> 

Dies erzeugt:

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 für "Wiederverwendung" meines Codes :) –

3

Diese Transformation:

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

wenn auf einem beliebigen XML-Dokument angewendet (nicht verwendet), produziert die korrektes Ergebnis wollte:

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

Sie haben sich die Mühe gemacht, die Parameter '$ pTarget' und' $ pReplacement' zu definieren, vermutlich mit der Absicht, die 'replace'-Vorlage dynamisch zu machen, aber Sie verwenden sie dann nicht, wo es darauf ankommt. – JLRishe

+0

@JLRishe, Ja, das ist * per Design * :) Beachten Sie, dass ich diese Parameter als * Standardwerte * geeignet angegeben habe. Das Ergebnis ist, dass ich sie im äußersten Aufruf der Vorlage in diesem speziellen Fall weglassen kann. –

+0

Ich beziehe mich nicht darauf, sie aus dem Vorlagenaufruf zu entfernen - ich beziehe mich darauf, sie überhaupt nicht in diesen Zeilen zu verwenden: ' ',' \' ',' '. Wenn jemand Werte für diese Parameter tatsächlich übergibt, würde er immer noch '' '->' 'ersetzen. – JLRishe

0

Dies ist nur eine Implementierung der JLRische-Novachev Lösung tat ich meine xml zu erreichen. Vielleicht kann es sehr nützlich sein:

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

... 

Ausgang:

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