使用XSLT转换含值内逗号的CSV数据为XML的方案咨询
解决方案
核心问题为原有逻辑直接按逗号分割CSV行,未识别双引号包裹的字段边界,导致字段内的逗号被误判为字段分隔符。可通过XSLT的analyze-string指令匹配符合CSV规则的字段修复,以下是完整修改后的代码:
完整修改后XSLT代码
<xsl:template match="/"> <xsl:variable name="input" select="unparsed-text('example.csv')" /> <xsl:variable name="rows" select="tokenize($input, '\r?\n')[normalize-space(.) != '']"/> <!-- 拆分表头,支持双引号包裹的表头场景 --> <xsl:variable name="csvHeaders"> <Heading> <xsl:analyze-string select="$rows[1]" regex='"([^"]*)"|([^,"]+)'> <xsl:matching-substring> <header> <xsl:value-of select="if (regex-group(1) != '') then regex-group(1) else regex-group(2)"/> </header> </xsl:matching-substring> </xsl:analyze-string> </Heading> </xsl:variable> <!-- 拆分数据行,支持双引号包裹的含逗号字段 --> <xsl:variable name="step1-xml"> <xsl:for-each select="remove($rows, 1)"> <data> <xsl:analyze-string select="." regex='"([^"]*)"|([^,"]+)'> <xsl:matching-substring> <xsl:element name="elm{position()}"> <xsl:value-of select="if (regex-group(1) != '') then regex-group(1) else regex-group(2)"/> </xsl:element> </xsl:matching-substring> </xsl:analyze-string> </data> </xsl:for-each> </xsl:variable> <CSVData> <xsl:copy-of select="$csvHeaders" /> <Dataset> <xsl:for-each select="$step1-xml/data"> <item> <xsl:for-each select="*"> <xsl:variable name="i" select="position()" /> <xsl:element name="{translate($csvHeaders/Heading/header[$i], ' :', '__')}"> <xsl:value-of select="."/> </xsl:element> </xsl:for-each> </item> </xsl:for-each> </Dataset> </CSVData> </xsl:template>
逻辑说明
- 用
analyze-string配合正则"([^"]*)"|([^,"]+)匹配CSV字段:优先匹配双引号包裹的内容,再匹配不含逗号和双引号的普通字段 - 匹配到双引号包裹的字段时,自动去掉外层双引号,保留内部逗号
- 新增空行过滤逻辑,避免CSV末尾空行导致的解析错误
- 完全兼容原有普通CSV的处理逻辑,无需额外预处理步骤
上述代码处理你提供的异常场景CSV时,可直接输出期望结果。
内容的提问来源于stack exchange,提问作者devforweb_17
相关产品推荐
相关产品推荐

