在 XSLT 代码中从 csv 读取空值而不移动单元格值
Posted
技术标签:
【中文标题】在 XSLT 代码中从 csv 读取空值而不移动单元格值【英文标题】:Reading null values from csv in XSLT code without shifting the cells values 【发布时间】:2021-05-26 17:24:42 【问题描述】:我有这两行来自 csv 文件
<ROOT>
1,M,40,0,5,0,Personeelsvoorschot,0
2,M,40,0,6,0,Personeelsvoorschot,0
</ROOT>
在 XSLT 代码中,我得到标签中的每个单元格,如下所示(行号、虚拟 1 等),但是当我尝试将任何具有空值的单元格并进行测试时,问题发生了,标签没有得到null ,它获取下一个错误的单元格值,我会感谢你的帮助
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common"extension-element-prefixes="exsl">
<xsl:output method="xml" encoding="UTF-8" indent="no" byte-order-mark="no"/>
<xsl:strip-space elements="*"/>
<!--<xsl:preserve-space elements="*"/>-->
<xsl:template match="@*|node()">
<xsl:copy >
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:key name="k1" match="row" use="cell[0]"/>
<xsl:key name="k2" match="row" use="concat(cell[1], '|', cell[3])"/>
<xsl:template match="/">
<xsl:element name="ProcessSalaryJournals">
<xsl:variable name="rows">
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="ProcessADPMultilinkSalaryJournalUpload/DataArea/ADPMultilinkSalaryJournalUpload/ADPMultilinkSalaryJournalUploaddocument/ROOT"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="data">
<xsl:for-each select="exsl:node-set($rows)/row[position() > 0]">
<row>
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="."/>
<xsl:with-param name="delimiter" select="','"/>
<xsl:with-param name="name" select="'cell'"/>
</xsl:call-template>
</row>
</xsl:for-each>
</xsl:variable>
<!-- output -->
<SalaryJournals>
<xsl:for-each select="exsl:node-set($data)/row[count(. | key('k1', cell[1])[1]) = 1]">
<SalaryJournal>
<LineNumber>
<xsl:value-of select="cell[1]"/>
</LineNumber>
<Dummy1>
<xsl:value-of select="cell[2] " />
</Dummy1>
<Dummy2>
<xsl:value-of select="cell[3] " />
</Dummy2>
<Dummy3>
<xsl:value-of select="cell[4] " />
</Dummy3>
<Dummy4>
<xsl:value-of select="cell[5] " />
</Dummy4>
<Dummy5>
<xsl:value-of select="cell[6] " />
</Dummy5>
<VoucherText>
<xsl:value-of select="cell[7] " />
</VoucherText>
<AccountingDate>
<xsl:value-of select="cell[8] " />
</AccountingDate>
</SalaryJournal>
</xsl:for-each>
</SalaryJournals>
</xsl:element>
<xsl:apply-templates select="@*|node()"/>
</xsl:template>
<xsl:template name="tokenize">
<xsl:param name="text"/>
<xsl:param name="delimiter" select="' '"/>
<xsl:param name="name" select="'row'"/>
<xsl:variable name="token" select="substring-before(concat($text, $delimiter), $delimiter)" />
<xsl:if test="$token">
<xsl:element name="$name">
<xsl:value-of select="$token"/>
</xsl:element>
</xsl:if>
<xsl:if test="contains($text, $delimiter)">
<!-- recursive call -->
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
<xsl:with-param name="delimiter" select="$delimiter"/>
<xsl:with-param name="name" select="$name"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
【问题讨论】:
输入数据如何准确地查找“null”值?为什么 XSLT 有version="2.0"
却使用非常 XSLT 1.0 的习语,如 Muenchian 分组和命名模板来标记化,尽管 XSLT 2.0 有 for-each-group
和 tokenize
函数?
数据将类似于 1,M,,0,5,,Personelsvoorschot,0 而不是 1,M,40,0,5,0,Personelsvoorschot,0
您使用 XSLT 2.0 处理器吗?
我认为xsl:if test="$token"
需要删除
是的,当我删除 xsl:if test="$token" 谢谢 :)
【参考方案1】:
如果用于标记化的模板需要找到空字符串标记,例如1,M,,0,5,,Personeelsvoorschot,0
中两个逗号之间的空字符串,我认为需要删除 xsl:if test="$token"
。
【讨论】:
以上是关于在 XSLT 代码中从 csv 读取空值而不移动单元格值的主要内容,如果未能解决你的问题,请参考以下文章
在JavaScript / jQuery中从列中获取所有值而不重复
在用户输入值而不覆盖以前的值后,如何写入 .csv 文件的下一行?
有没有办法使用 read.csv 从字符串值而不是 R 中的文件读取?