如何将复杂的xml转换成csv?

dddzy1tm  于 2021-07-12  发布在  Java
关注(0)|答案(2)|浏览(472)

我正在用java写一个程序(初级),我真的需要xslt转换方面的帮助。有必要从xml生成csv文件。我得到了这个xslt过滤器:

<?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" omit-xml-declaration="yes" indent="no"/>

    <xsl:template match="node()" name="conv">
        <xsl:call-template name="loop"/>
    </xsl:template>

    <xsl:template name="loop">

        <xsl:for-each select="./*[count(*) = 0]">
            <xsl:value-of select="."/>
            <xsl:if test="position() != last()">
                <xsl:text>,</xsl:text>
            </xsl:if>
            <xsl:if test="position() = last()">
                <xsl:text>,</xsl:text>
            </xsl:if>
        </xsl:for-each>
        <xsl:text>&#xA;</xsl:text>

        <xsl:for-each select="./*[(count(*) != 0) and (name()!='PARAMETRS')] ">
            <xsl:call-template name="loop"/>
        </xsl:for-each>
            <xsl:text>&#xA;</xsl:text>
    </xsl:template>
</xsl:stylesheet>

源xml:

<Integration>
    <PARAMETRS>
        <ID>AZD</ID>
        <DATE>2020-01-01</DATE>
    </PARAMETRS>
    <ORG>
        <Thing>
            <object>10220</object>
            <type>U</type>
            <dyn>
                <items>
                    <val>988009</val>
                    <datebegin>2019-12-12</datebegin>
                </items>
            </dyn>
        </Thing>
        <Thing>
            <object>10221</object>
            <type>U</type>
            <dyn>
                <items>
                    <val>988010</val>
                    <datebegin>2019-12-13</datebegin>
                </items>
                <items>
                    <val>988011</val>
                    <datebegin>2019-12-14</datebegin>
                </items>
            </dyn>
        </Thing>
    </ORG>
</Integration>

在输出中,我得到逗号分隔的行,还有几行(那些相同的项)带有下面的值。而且不知道如何连接这些值。。。我会通过select=“concat”的值来做,但是我的可能有几个dyn(1,2,3…),因此这是不合适的。输出需要用逗号分隔的csv。请告知如何将项与其父项连接起来?或者有更简单的方法用不同数量的子部分(child)来解析xml。
预期产量:

10220,U,988009,2019-12-12
10221,U,988010,2019-12-13,988011,2019-12-14
nnsrf1az

nnsrf1az1#

使用以下样式表可以很容易地获得您显示的输出:
xslt 1.0版

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

<xsl:template match="/Integration">
    <xsl:for-each select="ORG/Thing">
        <xsl:value-of select="object"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="type"/>
        <xsl:text>,</xsl:text>
        <xsl:for-each select="dyn/items">
            <xsl:value-of select="val"/>
            <xsl:text>,</xsl:text>
            <xsl:value-of select="datebegin"/>
            <xsl:if test="position() != last()">
                <xsl:text>,</xsl:text>
            </xsl:if>
        </xsl:for-each>
        <xsl:text>&#xA;</xsl:text>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

请注意,每个输出都有一组列 items ; 这不是一个理想的csv结构。

rsl1atfo

rsl1atfo2#

如果可以使用XSLT2.0,它将打开新的强大功能。
oracle xml developer kit(xdk)支持xslt 2.0
下面是链接:使用xslt处理器for java
以下方法执行以下操作:
使用 string-join() 函数通过 .//*/(text()[1] 表情。 xs:token 强制转换将删除空白。
xpath predicate [. != ''] 删除空序列成员。
xslt 2.0版

<?xml version='1.0'?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output method="text"/>

    <xsl:template match="/Integration">
        <xsl:for-each select="ORG/Thing">
            <xsl:value-of select="string-join((.//*/(text()[1] cast as xs:token?))[. != ''],',')"/>
            <xsl:text>&#xA;</xsl:text>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

输出

10220,U,988009,2019-12-12
10221,U,988010,2019-12-13,988011,2019-12-14

基于MartingHonnen的绝妙技巧,这里有一个更简洁的XSLT2.0版本,没有任何循环。
xslt 2.0版

<?xml version="1.0"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output method="text"/>

    <xsl:template match="/Integration">
        <xsl:value-of select="ORG/Thing/string-join((.//*/(text()[1] cast as xs:token?))[. != ''],',')" separator="&#xA;"/>
    </xsl:template>
</xsl:stylesheet>

相关问题