2014-04-24 71 views
1

我一直在致力於xml轉換爲csv並使用Convert an XML file to CSV file using java方法。但是,我的.xsl文件不能生成預期的.csv結果。使用XSL轉換將XML轉換爲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,',','&#xA;')"/> 
       </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 
+1

這不是一個有效的XML文檔,因爲它沒有根元素。 – samjudson

+0

@samjudson你是對的,但我沒有出現所有的XML文件。 – user3560030

回答

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', '&#xA;')"/> 
     <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])), 
        '&#xA;')"/> 
     </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', '&#xA;')"/> 
     <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>&#xA;</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> 

毫無疑問,更優雅的解決方案。

+0

非常感謝,最後如果有超過2列,它如何實現 – user3560030

+0

我已經更新了N列版本。您可能需要調整列標題以及'RowValue,Value' – StuartLC

+0

此解決方案在最後一次添加時正常工作。 – user3560030

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>&#10;</xsl:text> 
     </xsl:if> 
    </xsl:for-each> 
</xsl:template> 

</xsl:stylesheet> 

這將適應任何數量的,你可能有列。請注意,假定每個「列」(即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 
+0

根據這個解決方案,我得到了一個空白的csv輸出,因爲它沒有出現在eclipse中。 – user3560030

+1

@ user3560030你得到一個空輸出使用哪個輸入?我之所以使用自己的測試輸入是有原因的:您的輸入無效。 –