我想将以下XML转换为JSON:
<Table>
<Row>
<Column name="Column 1">outter quotation text and &qout;inner quotation text&qout;</Column>
<Column name="Column 2">
Some text with two 'new line' characters at the beginning (sometimes with &qout;inner quotation text&qout; also)</Column>
</Row>
</Table>
要拥有有效的json,我应删除所有“新行”字符(

)并将&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, '
'), '
')" />
<xsl:if test="contains($pText, '
')">
<xsl:text></xsl:text>
<xsl:call-template name="escapeNewLine"><xsl:with-param name="pText" select="substring-after($pText, '
')" /></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, '&qout;'), '&qout;')" />
<xsl:if test="contains($pText, '&qout;')">
<xsl:text>\"</xsl:text>
<xsl:call-template name="escapeQuote">
<xsl:with-param name="pText" select="substring-after($pText, '&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 &qout;inner quotation text&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 &qout;inner quotation text&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 :(得分: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('"', @name, '":')" />
<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="'
'" />
<xsl:with-param name="to" select="'\n'" />
</xsl:call-template>
</xsl:with-param>
<xsl:with-param name="from" select="'
'" />
<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="'&qout;'" />
<xsl:with-param name="to" select="'\"'" />
</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>