我一直在使用Convert an XML file to CSV file using java方法处理xml到csv转换。但是我的.xsl文件无法产生预期的.csv结果。
我该怎么办?我该如何更改我的.xsl文件?
这是我的.xml文件:
<RowOfValues>
<RowValue>
<Value>XYZ</Value>
</RowValue>
<RowValue>
<Value>xyz1</Value>
</RowValue>
<RowValue>
<Value>xyz2</Value>
</RowValue>
<RowValue>
<Value>xyz3</Value>
</RowValue>
<RowValue>
<Value>xyz4</Value>
</RowValue>
</RowOfValues>
<RowOfValues>
<RowValue>
<Value>ABC</Value>
</RowValue>
<RowValue>
<Value>abc1</Value>
</RowValue>
<RowValue>
<Value>abc2</Value>
</RowValue>
<RowValue>
<Value>abc3</Value>
</RowValue>
<RowValue>
<Value>abc4</Value>
</RowValue>
</RowOfValues>
这是我的.xsl文件:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" >
<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
<xsl:template match="/">
RowValue,Value
<xsl:for-each select="//RowOfValues">
<xsl:for-each select="//RowValue">
<xsl:value-of select="concat(Value,',','
')"/>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
当前结果(csv):
RowValue,值
XYZ,
xyz1,
xyz2,
xyz3,
xyz4,
ABC,
abc1,
abc2,
abc3,
abc4,
预期结果(csv):
RowValue,Value
XYZ ABC
xyz1,abc1
xyz2,abc2
xyz3,abc3
xyz4,abc4
答案 0 :(得分:0)
假设只有2列(即RowOfValues
),并假设两列的长度相同:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format" >
<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
<xsl:template match="/">
<xsl:value-of select="concat('RowValue,Value', '
')"/>
<xsl:for-each select="//RowOfValues[1]/RowValue">
<xsl:variable name="pos" select="position()"/>
<xsl:value-of select="concat(normalize-space(
concat(., ',', //RowOfValues[2]/RowValue[position()=$pos])),
'
')"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
修改强>
这是使用调用模板接近N列案例的一种方法,尽管相当必要:(
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format" >
<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
<xsl:template match="/">
<xsl:value-of select="concat('RowValue,Value', '
')"/>
<xsl:for-each select="//RowOfValues[1]/RowValue">
<xsl:variable name="pos" select="position()"/>
<xsl:value-of select="normalize-space(.)"/>
<xsl:call-template name="ScrapeColumns">
<xsl:with-param name="pos" select="$pos"/>
</xsl:call-template>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
<xsl:template name="ScrapeColumns">
<xsl:param name="pos"></xsl:param>
<xsl:for-each select="//RowOfValues[position() > 1]//RowValue[position()=$pos]">
<xsl:value-of select="concat(', ', normalize-space(.))"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
毫无疑问,更优雅的解决方案。
答案 1 :(得分:0)
如果有超过2列,它如何实现
以这种方式尝试:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:key name="value-by-column" match="Value" use="count(../preceding-sibling::RowValue)" />
<xsl:template match="/">
<xsl:for-each select="root/RowOfValues[1]/RowValue">
<xsl:for-each select="key('value-by-column', count(preceding-sibling::RowValue))">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:if test="position()!=last()">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
这将容纳您可能拥有的任意数量的列。注意,假设每个&#34;列中的值的数量为&#34; (即RowOfValues
)是平等的。
当应用于以下测试文档时:
<root>
<RowOfValues>
<RowValue>
<Value>Col A</Value>
</RowValue>
<RowValue>
<Value>a 1</Value>
</RowValue>
<RowValue>
<Value>a 2</Value>
</RowValue>
</RowOfValues>
<RowOfValues>
<RowValue>
<Value>Col B</Value>
</RowValue>
<RowValue>
<Value>b 1</Value>
</RowValue>
<RowValue>
<Value>b 2</Value>
</RowValue>
</RowOfValues>
<RowOfValues>
<RowValue>
<Value>Col C</Value>
</RowValue>
<RowValue>
<Value>c 1</Value>
</RowValue>
<RowValue>
<Value>c 2</Value>
</RowValue>
</RowOfValues>
</root>
结果是:
Col A,Col B,Col C
a 1,b 1,c 1
a 2,b 2,c 2