2012-02-21 47 views
13

我有以下xslt將數據轉換爲JQuery接受的格式。但是,因爲JSON不接受的數據串雙引號,我需要 「有一個轉義序列\」 來代替XSLT +用換碼序列替換雙引號

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:

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

電流輸出:

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

所需的輸出:

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

user1130511:心不是轉義字符'\'(反斜線)? – 2012-02-21 01:20:03

+0

user1130511:提供的XSLT代碼格式不正確 - 現在沒有人可以使用它。請編輯問題並更正。 – 2012-02-21 01:31:40

+0

@DimitreNovatchev woops,複製錯誤的版本。我已經更新了XSLT,應該可以工作。是的,它應該是一個反斜槓 – user1130511 2012-02-21 02:32:21

回答

26

此模板添加到您的代碼

<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:value-of select="."/> 

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

你徹底改造,現在變成

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

當這種轉變是在所提供的XML文檔應用:

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

通緝,產生正確的結果

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

對不起,我對XSLT比較陌生。是否有可能通過添加一些屬性自動將此模板應用於所有值,比如說「body/row」? – 2015-09-18 06:37:40

+1

@JamesCazzetta,需要調用一個已命名的模板。我強烈建議您參加XSLT培訓課程,例如:http://www.pluralsight.com/courses/xslt-foundations-part1 – 2015-09-18 15:07:26