我是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
我希望相关元素出现在一行上,如上所述。
由于
答案 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>
</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>
</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>
</xsl:text>
<!-- Process nodes having childs -->
<xsl:for-each select="./*[count(*) != 0]">
<xsl:value-of select="name()"/>
<xsl:text>
</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>
</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中加入最终版