xml - 如何在 XML 输出中嵌入 CSV 文件
问题描述
我正在尝试使用 XSLT 将 CSV(逗号分隔文件)转换为 XML。
CSV 样本:
AcctEntryId,ValueDate,Entity,Folder,DenomCcy,FunctCcy
321,2017-08-29,ABC NY,My Portfolio/PAC,BR,US
322,2017-08-30,ABC NY,My Portfolio/PBC,BR,US
323,2017-08-31,ABC NY,My Portfolio/PCC,BR,US
所需的 XML 输出:
<?xml version="1.0" encoding="utf-8"?>
<ProcessResponse xmlns="http://com.test.ws/">
<ProcessResult><Data DataNodeName="CData" DataType="TEXT"><CData><![CDATA[AcctEntryId,ValueDate,Entity,Folder,DenomCcy,FunctCcy
321,2017-08-29,ABC NY,My Portfolio/PAC,BR,US
322,2017-08-30,ABC NY,My Portfolio/PBC,BR,US
323,2017-08-31,ABC NY,My Portfolio/PCC,BR,US
]]></CData></Data>
</ProcessResult>
</ProcessResponse>
我想从 sap 的 AL11 文件夹中选择 CSV 文件。xslt 映射后的最终输出,我希望它是上面指定的所需格式的 XML 文件。
请您指导我如何编写 XSLT 代码以根据示例 CSV 数据生成上述 XML。
解决方案
这是一个 XSLT-2.0 或更高版本的解决方案。我不知道 SAP 是否支持这一点。如果没有,请参阅下面的 XSLT-1.0 hack。
您可以将 XSLT-2.0 函数unparsed-text()
与 RegEx 功能结合使用xsl:analyze-string
:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:variable name="csv" select="replace(unparsed-text('file:///home/kubuntu/Downloads/a.csv'),'utf-8','')"/>
<xsl:template match="/">
<xsl:element name="ProcessResponse" namespace="http://com.test.ws/">
<xsl:element name="ProcessResult" namespace="http://com.test.ws/">
<xsl:value-of select="'<Data DataNodeName="CData" DataType="TEXT"><CData><![CDATA['" />
<xsl:analyze-string select="$csv" regex='(.+)\n'>
<xsl:matching-substring>
<xsl:value-of select="concat(regex-group(1),'
')" />
</xsl:matching-substring>
<xsl:non-matching-substring><xsl:sequence select="."/></xsl:non-matching-substring>
</xsl:analyze-string>
<xsl:value-of select="']]></CData></Data>
'" />
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
输出符合预期,尽管它的要求对我来说似乎有点奇怪......
<?xml version="1.0" encoding="UTF-8"?>
<ProcessResponse xmlns="http://com.test.ws/">
<ProcessResult><Data DataNodeName="CData" DataType="TEXT"><CData><![CDATA[AcctEntryId,ValueDate,Entity,Folder,DenomCcy,FunctCcy
321,2017-08-29,ABC NY,My Portfolio/PAC,BR,US
322,2017-08-30,ABC NY,My Portfolio/PBC,BR,US
323,2017-08-31,ABC NY,My Portfolio/PCC,BR,US
]]></CData></Data>
</ProcessResult>
</ProcessResponse>
如果您仅限于 XSLT-1.0,则可以使用实体引用作为 hack ,如此 SO answer 中所述。
推荐阅读
- python - Python OpenCV - 添加状态栏以显示鼠标位置和颜色 RGB
- sql-server - 使用动态查询反透视
- r - (R) 优化错误 - 在定义函数时尝试应用非函数
- laravel - Laravel Web 应用程序中的 Firefox Web 浏览器?
- apache-kafka - 在 kafka 事件驱动的主干中保持服务同步
- ruby - 为什么就地修改 Ruby 字符串这么慢?
- c++ - 在 C++ 中使用库“xtensor-blas”时出错
- reactjs - 为什么 router.push 使用 next.js 重新加载/重新渲染页面?
- c# - 在 SQL Server 数据库中管理 SAAS 应用程序的用户
- vba - 从一个文档复制选定的文本并粘贴到页面上相同位置的新文档