2013-03-11 70 views
0

的结果,我想下面的XML转换成JSON:XSLT:应用模板的另一个

<Table> 
    <Row> 
     <Column name="Column 1">outter quotation text and &amp;qout;inner quotation text&amp;qout;</Column> 
     <Column name="Column 2"> 

Some text with two 'new line' characters at the beginning (sometimes with &amp;qout;inner quotation text&amp;qout; also)</Column> 
    </Row> 
</Table> 

要有有效的JSON,我应该删除所有“新行”字符(&#xA;)和替换&amp;qout;\"

貌似这个代码有助于消除 '新线':

<xsl:template name="escapeNewLine"> 
    <xsl:param name="pText" select="." /> 
     <xsl:if test="string-length($pText) > 0"> 
     <xsl:value-of select="substring-before(concat($pText, '&#xA;'), '&#xA;')" /> 
     <xsl:if test="contains($pText, '&#xA;')"> 
      <xsl:text></xsl:text> 
      <xsl:call-template name="escapeNewLine"><xsl:with-param name="pText" select="substring-after($pText, '&#xA;')" /></xsl:call-template> 
     </xsl:if> 
    </xsl:if> 
</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, '&amp;qout;'), '&amp;qout;')" /> 
      <xsl:if test="contains($pText, '&amp;qout;')"> 
       <xsl:text>\"</xsl:text> 
       <xsl:call-template name="escapeQuote"> 
        <xsl:with-param name="pText" select="substring-after($pText, '&amp;qout;')" /> 
       </xsl:call-template> 
      </xsl:if> 
     </xsl:if> 
    </xsl:template> 

我的样式表:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:output method="text" /> 
<xsl:template match="/"> 
"data":[ 
<xsl:for-each select="Table/Row"> 
    <xsl:if test="position() > 1">,</xsl:if> 
    { 
    <xsl:for-each select="Column"> 
     <xsl:if test="position() > 1">,</xsl:if> 
     "<xsl:value-of select="@name" />": 
     " 
     <xsl:call-template name="escapeQuote" /> 
     <xsl:call-template name="escapeNewLine" /> 
     <!-- <xsl:value-of select="." /> --> 
     " 
    </xsl:for-each> 
    } 
</xsl:for-each>] 
</xsl:template> 
</xsl:stylesheet> 

我的问题是如何将两个模板应用于同一个节点?所以不是这样的:

{"data":[ 
    {"Column 1":"outter quotation text and \"inner quotation text\" outter quotation text and &amp;qout;inner quotation text&amp;qout;"},  
    {"Column 2":"Some text with two 'new line' characters at the beginning (maybe with \"inner quotation text\" also) 

    Some text with two 'new line' characters at the beginning (maybe with &amp;qout;inner quotation text&amp;qout; also)"}} 
]} 

我能有这样的结果:

{"data": 
    [{"Column 1":"outter quotation text and \"inner quotation text\""}, 
    {"Column 2":"Some text with two 'new line' characters at the beginning (maybe with \"inner quotation text\" also)"}} 
    ]} 
+0

您在输入XML和XSLT中使用'& qout;'。那是故意的吗?它应该是“&”还是“"”? – JLRishe 2013-03-11 14:07:17

+0

是的,这很荒谬)但我没有影响xml输入 – 2013-03-11 15:04:02

回答

1

这就是你需要做什么:

<xsl:call-template name="escapeQuote"> 
    <xsl:with-param name="pText"> 
    <xsl:call-template name="escapeNewLine" /> 
    </xsl:with-param> 
</xsl:call-template> 


也有可能在这里有一些代码重用,并将两种换行符转换为\r\n,而不是将其删除:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="text" /> 
    <xsl:template match="/"> 
    "data":[ 
    <xsl:apply-templates select="Table/Row" /> 
    ] 
    </xsl:template> 

    <xsl:template match="Row" name="RowData"> 
    { 
    <xsl:apply-templates select="Column" /> 
    } 
    </xsl:template> 

    <xsl:template match="Row[position() > 1]"> 
    <xsl:text>,</xsl:text> 
    <xsl:call-template name="RowData" /> 
    </xsl:template> 

    <xsl:template match="Column" name="ColumnData"> 
    <xsl:value-of select="concat('&quot;', @name, '&quot;:')" /> 

    <xsl:text>"</xsl:text> 
    <xsl:call-template name="escapeQuote"> 
     <xsl:with-param name="pText"> 
     <xsl:call-template name="escapeNewLine" /> 
     </xsl:with-param> 
    </xsl:call-template> 
    <xsl:text>"</xsl:text> 
    </xsl:template> 

    <xsl:template match="Column[position() > 1]"> 
    <xsl:text>,</xsl:text> 
    <xsl:call-template name="ColumnData" /> 
    </xsl:template> 

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

    <xsl:call-template name="replace"> 
     <xsl:with-param name="pText"> 
     <xsl:call-template name="replace"> 
      <xsl:with-param name="pText" select="$pText" /> 
      <xsl:with-param name="from" select="'&#xA;'" /> 
      <xsl:with-param name="to" select="'\n'" /> 
     </xsl:call-template> 
     </xsl:with-param> 
     <xsl:with-param name="from" select="'&#xD;'" /> 
     <xsl:with-param name="to" select="'\r'" /> 
    </xsl:call-template> 
    </xsl:template> 

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

    <xsl:call-template name="replace"> 
     <xsl:with-param name="pText" select="$pText" /> 
     <xsl:with-param name="from" select="'&amp;qout;'" /> 
     <xsl:with-param name="to" select="'\&quot;'" /> 
    </xsl:call-template> 
    </xsl:template> 

    <xsl:template name="replace"> 
    <xsl:param name="pText" /> 
    <xsl:param name="from" /> 
    <xsl:param name="to" /> 

    <xsl:if test="string-length($pText) > 0"> 
     <xsl:value-of select="substring-before(concat($pText, $from), $from)" /> 
     <xsl:if test="contains($pText, $from)"> 
     <xsl:value-of select="$to" /> 
     <xsl:call-template name="replace"> 
      <xsl:with-param name="pText" select="substring-after($pText, $from)" /> 
      <xsl:with-param name="from" select="$from" /> 
      <xsl:with-param name="to" select="$to" /> 
     </xsl:call-template> 
     </xsl:if> 
    </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 
+0

这正是我需要的,谢谢 – 2013-03-11 15:19:54