XSLT将未知XML转换为CSV

时间:2015-11-27 11:01:01

标签: xml csv xslt

我是XSLT的新手,并且一直在努力解决以下问题。如果有人能帮助我解决这个问题,我感激不尽。

这是我的XML文件,但元素名称每次都可能不同。 XML是在运行时创建的。基本上我不知道XML文件中的所有元素。可能有更多或更少的元素,但基本上有以下结构:

    <University>
    <language>en</language>
    <name>Medi University</name>
    <location>Rome</location>
    <country>Italy</country>
    <member>
        <teacher>
                <name>John Sting</name>
                <joined>
                    <time>
                    <start/>
                        <end/>
                     </time>
                    <valid>true</valid>
                </joined>
                <name>Paul Ironman</name>
                <joined>
                    <time>
                    <start/>
                        <end/>
                     </time>
                    <valid>true</valid>
                </joined>
        </teacher>
        <teacherAssistant>
               <name>Luna Tutti</name>
                <joined>
                    <time>
                         <start>1.9.2015</start>
                        <end></end>
                    </time>
                    <valid>true</valid>
                </joined>
        </teacherAssistant>
     </member>
    <telephone>7538476398754</telephone>
    <email>medi@medi.com</email>
</University>

我有这个尝试转换它的XSLT文件。正如我所说,XML文件是在运行时创建的,我不知道XML内容。

 <xsl:template match="/">
      <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="*">
   <xsl:value-of select="name()"/>
      <xsl:value-of select="text()"/>
      <xsl:if test="*">
          <xsl:apply-templates/>
      </xsl:if>
  </xsl:template>
</xsl:stylesheet>

以上代码打印CSV文件,如下所示:

elemenNameelementValue
elemenName2elementValue2
elemenName3elementValue3

等等。

我想要的是下面的东西:

University

language, name, location, country,telephone, email
english, Medi, Rome,Italy,7538476398754,medi@medi.com

Teacter

name, joined, time, start,end,valid,
John Sting, , , , ,true
Paul Ironman, , , , , true

Teacher Assistant

name, joined, time, start,end,valid,
Luna Tutti, , ,1.9.2015, , true 

我希望相关元素出现在一行上,如上所述。

由于

2 个答案:

答案 0 :(得分:2)

试试这个真正通用的样式表

<?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()">
        <xsl:value-of select="name()"/>
        <xsl:text>&#xA;</xsl:text>
        <xsl:call-template name="loop"/>
    </xsl:template>

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

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

        <!-- Process nodes having childs -->
        <xsl:for-each select="./*[count(*) != 0]">
            <xsl:value-of select="name()"/>
            <xsl:text>&#xA;</xsl:text>
            <xsl:call-template name="loop"/>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

正如michael.hor257k所提到的,没有一些约束,每个具有子节点的节点都会启动新表。

尝试此替换

<!-- Process nodes having childs -->
<xsl:for-each select="./*[count(*) != 0]">
    <xsl:choose>
        <xsl:when test="name() = 'teacher'">
            <xsl:text>Teacher</xsl:text>
        </xsl:when>
        <xsl:when test="name() = 'teacherAssistant'">
            <xsl:text>Teacher Assistant</xsl:text>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="name()"/>
        </xsl:otherwise>
    </xsl:choose>

    <xsl:text>&#xA;</xsl:text>
    <xsl:call-template name="loop"/>
</xsl:for-each>

答案 1 :(得分:0)

您可以使用身份模板(如Using XSLT to copy all nodes in XML, with support for special cases中所述)并从那里开始工作。

例如,使用此代码

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">    
<xsl:template match="@*|node()">
        <xsl:value-of select="."/>
            <xsl:apply-templates select="@*|node()"/>
    </xsl:template>

</xsl:stylesheet>

输出结果为:

<?xml version="1.0" encoding="UTF-8"?>
en
Medi University
Rome
Italy


            John Sting





                true

            Paul Ironman





                true



           Luna Tutti


                     1.9.2015


                true



7538476398754
medi@medi.com

enen
Medi UniversityMedi University
RomeRome
ItalyItaly


            John Sting





                true

            Paul Ironman





                true



           Luna Tutti


                     1.9.2015


                true




            John Sting





                true

            Paul Ironman





                true


            John StingJohn Sting





                true








                truetrue

            Paul IronmanPaul Ironman





                true








                truetrue



           Luna Tutti


                     1.9.2015


                true


           Luna TuttiLuna Tutti


                     1.9.2015


                true


                     1.9.2015


                     1.9.20151.9.2015


                truetrue



75384763987547538476398754
medi@medi.commedi@medi.com

(请注意,我必须在你的XML中加入最终版