繁体   English   中英

如何将复杂的 Xml 转换为 csv?

[英]How to convert complex Xml to csv?

我正在用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>

在 output 中,我得到了逗号分隔的行,以及更多具有以下值的行(那些相同的项目)。 并且无法弄清楚如何连接这些值......我会通过 select = "concat" 的值来做到这一点,但我可能有几个 dyn (1, 2, 3...),因此这不合适。 output 需要用逗号分隔的 csv。 请告知如何将项目与其父级连接起来? 或者有更简单的方法来解析 xml 具有不同数量的小节(孩子)。

预期 output:

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

您展示的 output 可以使用以下样式表轻松获得:

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>

请注意,output 对每个items都有一组列; 这不是一个理想的 CSV 结构。

如果您可以使用 XSLT 2.0,它将开辟新的强大功能。

Oracle XML 开发人员套件 (XDK) 支持 XSLT 2.0

这是链接: 使用 XSLT 处理器用于 Java

下面的方法正在执行以下操作:

  • 使用string-join() function 通过.//*/(text()[1]表达式连接不同层次级别上的所有子元素值。
  • xs:token转换会删除空格。
  • XPath 谓词[. != ''] [. != '']删除空序列成员。

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>

Output

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

基于Marting Honnen的大技巧,这里更简洁的XSLT 2.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>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM