使用XSLT将CSV文件转换为XML

时间:2019-08-08 09:42:06

标签: xml csv xslt

我有需要转换为XML的CSV文件,但是问题是,我只需要某些字段,并且行数会改变。

我是XSLT的新手,无法弄清楚如何将此CSV转换为XML,尤其是CSV文件具有不同的行/行数。

该问题的Pastebin链接:https://pastebin.com/AfRxRRJX

例如:

示例输入数据如下:

1,12345,7654321,1,08/08/19,08/08/19
2,12345,12345678,3
2,12345,22345679,7
2,12345,32345680,6
2,12345,42345681,2
3,12345,

从人的角度来看数据是什么样的:

First line, ID, accountNo, ???, orderDate, orderDate
Product row, ID, productCode, quantity
Product row, ID, productCode, quantity
Product row, ID, productCode, quantity
Product row, ID, productCode, quantity
Last Line, ID,

输出应类似于:

<?xml version="1.0"?>
<orders>
    <order accountNo="7654321" orderDate="08/08/19">
        <orderItems>
            <orderItem productCode="12345678" quantity="3"/>
            <orderItem productCode="22345679" quantity="7"/>
            <orderItem productCode="32345680" quantity="6"/>
            <orderItem productCode="42345681" quantity="2"/>
        </orderItems>
    </order>
</orders>

我曾尝试将XSLT代码的不同片段组合在一起,但是在转换后,它总是垃圾。

================================================ ================================

我确实做了,但是不幸的是,我需要先将CSV转换为XML,然后再将XML转换为XML格式! '

         

<xsl:param name="csv-encoding" as="xs:string" select="'utf-8'"/>
<xsl:param name="csv-uri" as="xs:string" select="'file:///D:/csv%20to%20xml/example1.dat'"/>

<xsl:template match="/" name="csv2xml">
    <orders>
        <xsl:choose>
            <xsl:when test="unparsed-text-available($csv-uri, $csv-encoding)">
                <order>
                 <xsl:variable name="csv" select="unparsed-text($csv-uri, $csv-encoding)" />
                 <xsl:variable name="order-info" as="xs:string*">
                     <xsl:analyze-string select="$csv" regex="\r\n?|\n">
                         <xsl:non-matching-substring>
                             <xsl:if test="starts-with(., '1')">
                                 <xsl:copy-of select="tokenize(.,',')"/>
                             </xsl:if>
                         </xsl:non-matching-substring>
                     </xsl:analyze-string>
                 </xsl:variable>
                 <xsl:attribute name="accountNo">
                     <xsl:value-of select="$order-info[3]"/>
                 </xsl:attribute>
                <xsl:attribute name="orderDate">
                    <xsl:value-of select="$order-info[5]"/>
                </xsl:attribute>
                 <orderItems>
                     <xsl:analyze-string select="$csv" regex="\r\n?|\n">
                         <xsl:non-matching-substring>
                             <xsl:if test="starts-with(., '2')">
                                 <orderItem>
                                     <xsl:for-each select="tokenize(.,',')">
                                         <xsl:variable name="pos" select="position()"/>
                                         <xsl:if test="$pos=3">
                                             <xsl:attribute name="productCode">
                                                 <xsl:value-of select="."/>
                                             </xsl:attribute>    
                                         </xsl:if>
                                         <xsl:if test="$pos=4">
                                             <xsl:attribute name="quantity">
                                                 <xsl:value-of select="."/>
                                             </xsl:attribute>    
                                         </xsl:if>
                                     </xsl:for-each>
                                 </orderItem>
                             </xsl:if>
                         </xsl:non-matching-substring>
                     </xsl:analyze-string>
                 </orderItems>
                </order>
            </xsl:when>
            <xsl:otherwise>
                <test>
                </test>
            </xsl:otherwise>
        </xsl:choose>
    </orders>
</xsl:template>

'

1 个答案:

答案 0 :(得分:0)

您不能简单地做类似的事情吗?

<xsl:template match="/">
    <xsl:variable name="lines" select="tokenize($csv, '&#10;')" />
    <orders>
        <xsl:variable name="line1-fields" select="tokenize($lines[1], ',')" />
        <order accountNo="{$line1-fields[3]}" orderDate="{$line1-fields[5]}">
            <orderItems>
                <xsl:for-each select="$lines[not(position() = (1, last()))]">
                    <xsl:variable name="fields" select="tokenize(., ',')" />
                    <orderItem productCode="{$fields[3]}" quantity="{$fields[4]}"/>
                </xsl:for-each>
            </orderItems>
        </order>
    </orders>
</xsl:template>