使用 XSLT 2.0 将 CSV 转换为 XML - 跳过空行
CSV to XML conversion with XSLT 2.0 - Skip empty lines
背景:
我有一个 CSV 文件用于从外部资源输入,我正在将其转换为 XML。 XML 然后用于更多的转换工作。
我用来获取 CSV 到 XML 的函数来自 Andrew J. Welch:http://andrewjwelch.com/code/xslt/csv/csv-to-xml_v2.html.
<xsl:variable name="KortingOverzicht">
<xsl:call-template name="Kortingoverzicht">
<xsl:with-param name="pathToCSV" select="'discountoverview.csv'"/>
</xsl:call-template>
</xsl:variable>
<xsl:function name="fn:getTokens" as="xs:string+">
<xsl:param name="str" as="xs:string"/>
<xsl:analyze-string regex="("[^"]*")+" select="$str">
<xsl:matching-substring>
<xsl:sequence
select="replace(., "^""|""$|("")""", "")"
/>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:for-each select="tokenize(., '\s*,\s*')">
<xsl:sequence select="."/>
</xsl:for-each>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:function>
<xsl:template name="Kortingoverzicht">
<xsl:param name="pathToCSV"/>
<xsl:variable name="XMLkorting">
<xsl:choose>
<xsl:when test="unparsed-text-available($pathToCSV)">
<xsl:variable name="csv" select="unparsed-text($pathToCSV)"/>
<xsl:variable name="lines" select="tokenize($csv, '
')" as="xs:string+"/>
<xsl:variable name="elemNames" select="fn:getTokens($lines[1])" as="xs:string+"/>
<xsl:element name="Kortingoverzicht">
<xsl:for-each select="$lines[position() > 1]">
<Korting>
<xsl:variable name="lineItems" select="fn:getTokens(.)"
as="xs:string+"/>
<xsl:for-each select="$elemNames">
<xsl:variable name="pos" select="position()"/>
<elem name="{.}">
<xsl:value-of select="$lineItems[$pos]"/>
</elem>
</xsl:for-each>
</Korting>
</xsl:for-each>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:text>Bestand niet gevonden : </xsl:text>
<xsl:value-of select="$pathToCSV"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:element name="Kortingoverzicht">
<xsl:for-each select="$XMLkorting/Kortingoverzicht/Korting">
<xsl:element name="Korting">
<xsl:element name="brandid">
<xsl:value-of select="substring-before(elem,';')"/>
</xsl:element>
<xsl:element name="brandname">
<xsl:value-of select="substring-before(substring-after(elem,';'),';')"/>
</xsl:element>
<xsl:element name="discount">
<xsl:value-of select="substring-after(substring-after(elem,';'),';')"/>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
问题:
CSV 文件每天更新,"as is"。该文件的末尾始终包含一个空行。该函数不喜欢这样并给出错误:不允许空序列作为函数 fn:getTokens()
的结果
为了解决这个问题,我总是手动删除空行。但现在我希望整个 XSLT 自动 运行,最好不必手动删除行。
问题:
有没有办法改变函数或对它的调用,使其跳过任何空行?
如果将 <xsl:variable name="lines" select="tokenize($csv, '
')" as="xs:string+"/>
更改为 <xsl:variable name="lines" select="tokenize($csv, '
')[normalize-space()]" as="xs:string+"/>
,则忽略空行。
背景:
我有一个 CSV 文件用于从外部资源输入,我正在将其转换为 XML。 XML 然后用于更多的转换工作。 我用来获取 CSV 到 XML 的函数来自 Andrew J. Welch:http://andrewjwelch.com/code/xslt/csv/csv-to-xml_v2.html.
<xsl:variable name="KortingOverzicht">
<xsl:call-template name="Kortingoverzicht">
<xsl:with-param name="pathToCSV" select="'discountoverview.csv'"/>
</xsl:call-template>
</xsl:variable>
<xsl:function name="fn:getTokens" as="xs:string+">
<xsl:param name="str" as="xs:string"/>
<xsl:analyze-string regex="("[^"]*")+" select="$str">
<xsl:matching-substring>
<xsl:sequence
select="replace(., "^""|""$|("")""", "")"
/>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:for-each select="tokenize(., '\s*,\s*')">
<xsl:sequence select="."/>
</xsl:for-each>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:function>
<xsl:template name="Kortingoverzicht">
<xsl:param name="pathToCSV"/>
<xsl:variable name="XMLkorting">
<xsl:choose>
<xsl:when test="unparsed-text-available($pathToCSV)">
<xsl:variable name="csv" select="unparsed-text($pathToCSV)"/>
<xsl:variable name="lines" select="tokenize($csv, '
')" as="xs:string+"/>
<xsl:variable name="elemNames" select="fn:getTokens($lines[1])" as="xs:string+"/>
<xsl:element name="Kortingoverzicht">
<xsl:for-each select="$lines[position() > 1]">
<Korting>
<xsl:variable name="lineItems" select="fn:getTokens(.)"
as="xs:string+"/>
<xsl:for-each select="$elemNames">
<xsl:variable name="pos" select="position()"/>
<elem name="{.}">
<xsl:value-of select="$lineItems[$pos]"/>
</elem>
</xsl:for-each>
</Korting>
</xsl:for-each>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:text>Bestand niet gevonden : </xsl:text>
<xsl:value-of select="$pathToCSV"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:element name="Kortingoverzicht">
<xsl:for-each select="$XMLkorting/Kortingoverzicht/Korting">
<xsl:element name="Korting">
<xsl:element name="brandid">
<xsl:value-of select="substring-before(elem,';')"/>
</xsl:element>
<xsl:element name="brandname">
<xsl:value-of select="substring-before(substring-after(elem,';'),';')"/>
</xsl:element>
<xsl:element name="discount">
<xsl:value-of select="substring-after(substring-after(elem,';'),';')"/>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
问题:
CSV 文件每天更新,"as is"。该文件的末尾始终包含一个空行。该函数不喜欢这样并给出错误:不允许空序列作为函数 fn:getTokens()
的结果为了解决这个问题,我总是手动删除空行。但现在我希望整个 XSLT 自动 运行,最好不必手动删除行。
问题:
有没有办法改变函数或对它的调用,使其跳过任何空行?
如果将 <xsl:variable name="lines" select="tokenize($csv, '
')" as="xs:string+"/>
更改为 <xsl:variable name="lines" select="tokenize($csv, '
')[normalize-space()]" as="xs:string+"/>
,则忽略空行。