我正在使用xslt将xml转换为csv,下面是我的xsl文件:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cov="http://schemas.atlassian.com/clover3/report">
<xsl:output method="text"/>
<xsl:template match="testcase">
<xsl:value-of select ="@classname"/>
<xsl:text>,</xsl:text>
<xsl:value-of select ="@name"/>
<xsl:text>,</xsl:text>
<xsl:value-of select ="@time"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
csv文件看起来不错,所有的新行都在那里,但是当我尝试用hive(来自cloudera hadoop)使用以下查询创建外部表时:
Create external table csv_test(className STRING, testName STRING, duration DOUBLE)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
LOCATION '/TEST/';
对于csv文件中的每一行,我有两行,一行带有值,另一行带有空值。好像它没有正确地接受换行符,并且认为它是两行而不是一行。
我为新台词尝试了不同的技巧,例如
, 

, 
,
, \n
,前面代码的组合,甚至将标记放在两个独立的行上,但我得到了相同的结果。
另一个问题是第三个字段,持续时间。我总是有一个空值。在我的create table查询中,如果我用字符串替换double,它就会工作。
如果我用相同的数据手动创建cvs文件,那么一切(新行和双行)都可以正常工作,如果只使用xslt创建的csv文件,那么问题就来了。
我做错什么了吗?
2条答案
按热度按时间nszi6y051#
不同系统和程序之间的换行处理可能很棘手。您应该检查以下内容以确定哪里出错:
当处理器读取xml时,它的换行符都被转换成0x0a,也就是说,windows换行符(0x0d+0x0a)被转换成0x0a,任何剩余的单个0x0d(mac换行符)被0x0a替换。
如果不明确使用
xsl:stripspace
或者删除带有匹配模式的空文本节点,默认匹配模式将输出空白。在上面的示例中,如前所述,输入xml的换行将成为输出xml的一部分。即使实际存在双换行符,许多文本编辑器也会在显示它们之前对它们进行规范化。例如,在您的示例中,如果输入包含换行符,则输出可能包含0xa+0xd的序列,如果在windows中查看,这些序列看起来像单个换行符,但在其他系统中可能不会被解释为单个换行符。
在转换过程中一切正常之后,这取决于如何将输出移动到最终位置。如果使用ftp或github,可以转换换行符。您可以通过将它们显式地作为二进制文件移动来解决这个问题。
存在一些XSLT1.0处理器,当您使用
method="text"
匹配您所在平台的默认行尾(这不是正确的行为,但这是另一回事)。您没有提到您使用的处理器,但是您可以通过将结果文件作为二进制文件打开来检查这一点,并验证您只有0xa行结尾。通常,最安全的方法是对所有系统使用相同的行尾制度,并防止在文件从一个系统上载到另一个系统时进行隐式转换。
显然,hive当前会自动规范化行结束符,这意味着您要么遇到了hive的bug,要么使用了不稳定的hive构建,要么输出包含导致出现空记录的实际内容。对于后者,我们需要一个最小的、但完全可以工作的输入xml和xslt,您当前使用它来尝试重现您的问题。
问题在于
DOUBLE
这个领域很棘手。这可能取决于本地化设置,但我不知道足够的Hive来证明这一点。假设您的本地化是德语,则双精度值写为23.456,98,在英语区域设置中为23456.98。检查csv的格式以及是否与预期的输出匹配,或者将点转换为逗号或逗号。从输入中删除任何空白的xslt示例如下所示(可能还有其他选项):
vohkndzv2#
最后我使用python脚本读取xml文件并编写csv文件。我没有这样的格式问题。。。