使用java将XML文件转换为CSV文件(具有多个元素值)

时间:2014-05-09 14:24:50

标签: java xml xslt csv

我正致力于将XML解析为CSV。进入文章@ Convert an XML file to CSV file using java并能够使用data.xml和style.xsl验证解决方案

在xml data.xml的基础上,想知道如果某些元素存在多个值,那么style.xsl需要进行哪些更改。

例如,如果data.xml中有时存在多个操作系统

<?xml version="1.0"?>
<Sites>
<Site id="101" name="NY-01" location="New York">
<Hosts>
   <Host id="1001">
   <Host_Name>srv001001</Host_Name>
   <IP_address>10.1.2.3</IP_address>
   <OS>Windows</OS>
   <Load_avg_1min>1.3</Load_avg_1min>
   <Load_avg_5min>2.5</Load_avg_5min>
   <Load_avg_15min>1.2</Load_avg_15min>
</Host>
<Host id="1002">
   <Host_Name>srv001002</Host_Name>
   <IP_address>10.1.2.4</IP_address>
   <OS>Linux, Windows</OS>
   <Load_avg_1min>1.4</Load_avg_1min>
   <Load_avg_5min>2.5</Load_avg_5min>
   <Load_avg_15min>1.2</Load_avg_15min>
</Host>
<Host id="1003">
   <Host_Name>srv001003</Host_Name>
   <IP_address>10.1.2.5</IP_address>
   <OS>Linux</OS>
   <Load_avg_1min>3.3</Load_avg_1min>
   <Load_avg_5min>1.6</Load_avg_5min>
   <Load_avg_15min>1.8</Load_avg_15min>
</Host>
<Host id="1004">
   <Host_Name>srv001004</Host_Name>
   <IP_address>10.1.2.6</IP_address>
   <OS>Linux, NetBSD</OS>
   <Load_avg_1min>2.3</Load_avg_1min>
   <Load_avg_5min>4.5</Load_avg_5min>
   <Load_avg_15min>4.2</Load_avg_15min>
</Host>     

2 个答案:

答案 0 :(得分:1)

以这种方式试试吗?

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="text" encoding="utf-8"/>

<xsl:template match="/">
    <xsl:text>Host_Name,IP_address,OS,Load_avg_1min,Load_avg_5min,Load_avg_15min&#10;</xsl:text>
    <xsl:for-each select="Sites/Site/Hosts/Host">
        <xsl:value-of select="concat(Host_Name,',',IP_address,',&quot;',OS,'&quot;,',Load_avg_1min,',',Load_avg_5min,',',Load_avg_15min,'&#10;')"/>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

或者,如果您愿意:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="text" encoding="utf-8"/>

<xsl:template match="/">
    <xsl:text>Host_Name,IP_address,OS,Load_avg_1min,Load_avg_5min,Load_avg_15min&#10;</xsl:text>
    <xsl:for-each select="Sites/Site/Hosts/Host">
        <xsl:for-each select="*">
            <xsl:text>"</xsl:text>
            <xsl:value-of select="."/>
            <xsl:text>"</xsl:text>
            <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>

请注意,两者都没有假设您的&#34;字段&#34;包含"引号。

答案 1 :(得分:0)

如果您在元素中使用逗号分隔值,则可以在使用translate(node, character-to-be-replaced, replacement-character)进行转换时替换它:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="Host">
        <xsl:value-of select="ancestor::Site/@id"/><xsl:text>, </xsl:text>
        ...

        <xsl:value-of select="@id"/><xsl:text>, </xsl:text>
        <xsl:value-of select="Host_Name"/><xsl:text>, </xsl:text>
        <xsl:value-of select="IP_address"/><xsl:text>, </xsl:text>
        <xsl:value-of select="translate(OS, ',', ';')"/><xsl:text>, </xsl:text>
        ...
    </xsl:template>

</xsl:stylesheet>

您可以将它用于可能包含逗号的所有元素,因为如果找不到逗号,则将复制文本而不进行任何更改。