2012-02-21 13 views
13

Ho il seguente xslt per trasformare i dati in un formato accettato da JQuery. Tuttavia, poiché JSON non accetta virgolette doppie nella stringa di dati, ho bisogno di sostituire "con una sequenza di escape \"XSLT + Sostituzione di doppi apici con sequenza di escape

XML:

<?xml version="1.0" encoding="UTF-8"?> 
<Rowsets> 
    <Rowset> 
     <Columns> 
      <Column Description="Element_1" SQLDataType="12" /> 
      <Column Description="Element_2" SQLDataType="12" /> 
      <Column Description="Element_3" SQLDataType="93" /> 
     </Columns> 
     <Row> 
      <Element_1>test_data</Element_1> 
      <Element_2>test_quo"te</Element_2> 
      <Element_3>test_data</Element_3> 
     </Row> 
    </Rowset> 
</Rowsets> 

XSLT attuale:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:java="http://xml.apache.org/xslt/java" exclude-result-prefixes="java"> 
    <xsl:output method="text" media-type="text/csv" encoding="UTF-8"/> 
    <xsl:param name="RowDelim">],</xsl:param> 
    <xsl:param name="RowLast">]</xsl:param> 
    <xsl:param name="RowStart">[</xsl:param> 
    <xsl:param name="startBracket">{ </xsl:param> 
    <xsl:param name="JQTableData">"aaData": [</xsl:param> 
    <xsl:param name="JQTableEnd">] }</xsl:param> 
    <xsl:param name="FieldDelim">,</xsl:param> 
    <xsl:param name="StringDelim">"</xsl:param> 
    <xsl:param name="DateFormat">yyyy-MM-dd HH:mm:ss</xsl:param> 


    <xsl:template match="/"> 





     <xsl:for-each select="Rowsets"> 

      <xsl:for-each select="Rowset"> 
      <xsl:value-of select="$startBracket"/> 
      <xsl:value-of select="$JQTableData"/> 
       <xsl:variable name="CurrentColumns" select="Columns"/> 
       <xsl:for-each select="Columns"> 
        <xsl:for-each select="Column"> 

         <xsl:if test="not(position() = last())"> 

         </xsl:if> 
        </xsl:for-each> 

       </xsl:for-each> 
       <xsl:for-each select="Row"> 
       <xsl:value-of select="$RowStart"/> 
        <xsl:for-each select="*"> 
         <xsl:variable name="ColName"> 
          <xsl:value-of select="name(.)"/> 
         </xsl:variable> 
         <xsl:variable name="ColType"> 
          <xsl:value-of select="$CurrentColumns/Column[@Name=$ColName]/@SQLDataType"/> 
         </xsl:variable> 
         <xsl:choose> 
          <xsl:when test="$ColType= '2' or $ColType= '3' or $ColType= '4' or $ColType= '5' or 

$ColType= '6' or $ColType= '7' or $ColType= '8' or $ColType= '-7'"> 
           <xsl:value-of select="."/> 
          </xsl:when> 
          <xsl:otherwise> 
           <xsl:value-of select="$StringDelim"/> 
           <xsl:choose> 
            <xsl:when test="$ColType= '91' or $ColType= '92' or $ColType= '93'"> 
             <xsl:choose> 
              <xsl:when test=". = 'TimeUnavailable'"> 
               <xsl:value-of select="."/> 
              </xsl:when> 
              <xsl:otherwise> 
                         </xsl:otherwise> 
             </xsl:choose> 
            </xsl:when> 
            <xsl:otherwise> 
            <xsl:choose> 
             <xsl:when test=". = 'true'"> 
              <xsl:text>Y</xsl:text> 
             </xsl:when> 
             <xsl:when test=". = 'false'"> 
              <xsl:text>N</xsl:text> 
             </xsl:when> 
             <xsl:otherwise> 
              <xsl:value-of select="."/> 
             </xsl:otherwise> 
             </xsl:choose> 
            </xsl:otherwise> 
           </xsl:choose> 
           <xsl:value-of select="$StringDelim"/> 
          </xsl:otherwise> 
         </xsl:choose> 
         <xsl:if test="not(position() = last())"> 
          <xsl:value-of select="$FieldDelim"/> 
         </xsl:if> 
        </xsl:for-each> 
          <xsl:if test="not(position() = last())"> 
          <xsl:value-of select="$RowDelim"/> 
         </xsl:if> 
          <xsl:if test="position() = last()"> 
          <xsl:value-of select="$RowLast"/> 
         </xsl:if> 

       </xsl:for-each> 
       <xsl:value-of select="$JQTableEnd"/> 
      </xsl:for-each> 
     </xsl:for-each> 
    </xsl:template> 



</xsl:stylesheet> 

uscita in corrente:

{ "aaData": [["test_data","test_quo"te","test_data"]] } 

output desiderato:

{ "aaData": [["test_data","test_quo\"te","test_data"]] } 
+0

user1130511: non è il carattere di escape '\' (back-slash)? –

+0

user1130511: Il codice XSLT fornito non è ben strutturato, nessuno può lavorarci ora. Per favore, modifica la domanda e correggi. –

+0

@DimitreNovatchev woops, copiata versione errata. Ho aggiornato l'XSLT, che dovrebbe funzionare. E sì, dovrebbe essere un back-slash – user1130511

risposta

26

Aggiungi questo modello per il codice:

<xsl:template name="escapeQuote"> 
     <xsl:param name="pText" select="."/> 

     <xsl:if test="string-length($pText) >0"> 
     <xsl:value-of select= 
     "substring-before(concat($pText, '&quot;'), '&quot;')"/> 

     <xsl:if test="contains($pText, '&quot;')"> 
     <xsl:text>\"</xsl:text> 

     <xsl:call-template name="escapeQuote"> 
      <xsl:with-param name="pText" select= 
      "substring-after($pText, '&quot;')"/> 
     </xsl:call-template> 
     </xsl:if> 
     </xsl:if> 
    </xsl:template> 

Poi cambia:

<xsl:value-of select="."/> 

al:

<xsl:call-template name="escapeQuote"/> 

tua completa trasformazione diventa ora:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:java="http://xml.apache.org/xslt/java" exclude-result-prefixes="java"> 
     <xsl:output method="text" media-type="text/csv" encoding="UTF-8"/> 
     <xsl:param name="RowDelim">],</xsl:param> 
     <xsl:param name="RowLast">]</xsl:param> 
     <xsl:param name="RowStart">[</xsl:param> 
     <xsl:param name="startBracket">{ </xsl:param> 
     <xsl:param name="JQTableData">"aaData": [</xsl:param> 
     <xsl:param name="JQTableEnd">] }</xsl:param> 
     <xsl:param name="FieldDelim">,</xsl:param> 
     <xsl:param name="StringDelim">"</xsl:param> 
     <xsl:param name="DateFormat">yyyy-MM-dd HH:mm:ss</xsl:param> 


     <xsl:template match="/"> 

      <xsl:for-each select="Rowsets"> 

       <xsl:for-each select="Rowset"> 
       <xsl:value-of select="$startBracket"/> 
       <xsl:value-of select="$JQTableData"/> 
        <xsl:variable name="CurrentColumns" select="Columns"/> 
        <xsl:for-each select="Columns"> 
         <xsl:for-each select="Column"> 

          <xsl:if test="not(position() = last())"> 

          </xsl:if> 
         </xsl:for-each> 

        </xsl:for-each> 
        <xsl:for-each select="Row"> 
        <xsl:value-of select="$RowStart"/> 
         <xsl:for-each select="*"> 
          <xsl:variable name="ColName"> 
           <xsl:value-of select="name(.)"/> 
          </xsl:variable> 
          <xsl:variable name="ColType"> 
           <xsl:value-of select="$CurrentColumns/Column[@Name=$ColName]/@SQLDataType"/> 
          </xsl:variable> 
          <xsl:choose> 
           <xsl:when test="$ColType= '2' or $ColType= '3' or $ColType= '4' or $ColType= '5' or 

    $ColType= '6' or $ColType= '7' or $ColType= '8' or $ColType= '-7'"> 
            <xsl:value-of select="."/> 
           </xsl:when> 
           <xsl:otherwise> 
            <xsl:value-of select="$StringDelim"/> 
            <xsl:choose> 
             <xsl:when test="$ColType= '91' or $ColType= '92' or $ColType= '93'"> 
              <xsl:choose> 
               <xsl:when test=". = 'TimeUnavailable'"> 
                <xsl:value-of select="."/> 
               </xsl:when> 
               <xsl:otherwise> 
                          </xsl:otherwise> 
              </xsl:choose> 
             </xsl:when> 
             <xsl:otherwise> 
             <xsl:choose> 
              <xsl:when test=". = 'true'"> 
               <xsl:text>Y</xsl:text> 
              </xsl:when> 
              <xsl:when test=". = 'false'"> 
               <xsl:text>N</xsl:text> 
              </xsl:when> 
              <xsl:otherwise> 
               <xsl:call-template name="escapeQuote"/> 
               <!-- <xsl:value-of select="."/> --> 
              </xsl:otherwise> 
              </xsl:choose> 
             </xsl:otherwise> 
            </xsl:choose> 
            <xsl:value-of select="$StringDelim"/> 
           </xsl:otherwise> 
          </xsl:choose> 
          <xsl:if test="not(position() = last())"> 
           <xsl:value-of select="$FieldDelim"/> 
          </xsl:if> 
         </xsl:for-each> 
           <xsl:if test="not(position() = last())"> 
           <xsl:value-of select="$RowDelim"/> 
          </xsl:if> 
           <xsl:if test="position() = last()"> 
           <xsl:value-of select="$RowLast"/> 
          </xsl:if> 

        </xsl:for-each> 
        <xsl:value-of select="$JQTableEnd"/> 
       </xsl:for-each> 
      </xsl:for-each> 
     </xsl:template> 

     <xsl:template name="escapeQuote"> 
      <xsl:param name="pText" select="."/> 

      <xsl:if test="string-length($pText) >0"> 
      <xsl:value-of select= 
      "substring-before(concat($pText, '&quot;'), '&quot;')"/> 

      <xsl:if test="contains($pText, '&quot;')"> 
      <xsl:text>\"</xsl:text> 

      <xsl:call-template name="escapeQuote"> 
       <xsl:with-param name="pText" select= 
       "substring-after($pText, '&quot;')"/> 
      </xsl:call-template> 
      </xsl:if> 
      </xsl:if> 
     </xsl:template> 

</xsl:stylesheet> 

quando tale trasformazione viene applicato sul documento XML fornito:

<Rowsets> 
    <Rowset> 
     <Columns> 
      <Column Description="Element_1" SQLDataType="12" /> 
      <Column Description="Element_2" SQLDataType="12" /> 
      <Column Description="Element_3" SQLDataType="93" /> 
     </Columns> 
     <Row> 
      <Element_1>test_data</Element_1> 
      <Element_2>test_quo"te</Element_2> 
      <Element_3>test_data</Element_3> 
     </Row> 
    </Rowset> 
</Rowsets> 

The Wanted, il risultato corretto è prodotto:

{ "aaData": [["test_data","test_quo\"te","test_data"]] } 
+0

Mi dispiace, sono relativamente nuovo a XSLT. C'è la possibilità di applicare automaticamente questo modello a tutti i valori di, diciamo un "corpo/riga" aggiungendo qualche attributo? –

+1

@JamesCazzetta, è necessario chiamare un modello denominato. Consiglio vivamente di seguire un corso di formazione XSLT, come ad esempio: http://www.pluralsight.com/courses/xslt-foundations-part1 –

Problemi correlati