[下面尝试使用XSLT将XML文件解析为CSV。使用XSL解析的.CSV文件中下面提到的XML文件的预期结果
下面提到示例XML文件
<SCHOOLS>
<SCHOOL_DATA>
<SCHOOL>
<SCHOOL_NAME>Convent International</SCHOOL_NAME>
<SCHOOL_ADDRESS>Near x-Street</SCHOOL_ADDRESS>
</SCHOOL>
<STUDENT_DTLS>
<STUDENT>
<STUDENT_NAME>Maria</STUDENT_NAME>
<STUDENT_CLASS>10</STUDENT_CLASS>
</STUDENT>
<STUDENT>
<STUDENT_NAME>John</STUDENT_NAME>
<STUDENT_CLASS>12</STUDENT_CLASS>
</STUDENT>
</STUDENT_DTLS>
<SCHOOL_AWARDS>
<AWARDS>
<AWARD_NAME>A1</AWARD_NAME>
<AWARD_DATE>D1</AWARD_DATE>
</AWARDS>
<AWARDS>
<AWARD_NAME>A2</AWARD_NAME>
<AWARD_DATE>D2</AWARD_DATE>
</AWARDS>
<AWARDS>
<AWARD_NAME>A3</AWARD_NAME>
<AWARD_DATE>D3</AWARD_DATE>
</AWARDS>
<AWARDS>
<AWARD_NAME>A4</AWARD_NAME>
<AWARD_DATE>D4</AWARD_DATE>
</AWARDS>
</SCHOOL_AWARDS>
</SCHOOL_DATA>
</SCHOOLS>
使用上述示例数据通过Xsl解析的.csv中的预期输出
SCHOOL_NAME,SCHOOL_ADDRESS,STUDENT_NAME,STUDENT_CLASS,AWARD_NAME,AWARD_DATE
Convent International,Near x-Street,Maria,10,A1,D1
,,John,12,A2,D2
,,,,A3,D3
,,,,A4,D4
下车解析XML文件
SCHOOL_NAME,SCHOOL_ADDRESS,STUDENT_NAME,STUDENT_CLASS,AWARD_NAME,AWARD_DATE
Convent International,Near x-Street
,,Maria,10
,,John,12
,,,,A1,D1
,,,,A2,D2
,,,,A3,D3
,,,,A4,D4
Xslt文件
<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
<xsl:template match="/">
SCHOOL_NAME,SCHOOL_ADDRESS,STUDENT_NAME,STUDENT_CLASS,AWARD_NAME,AWARD_DATE
<xsl:for-each select="SCHOOLS/SCHOOL_DATA">
<xsl:for-each select="SCHOOL">
<xsl:value-of select="concat(SCHOOL_NAME,',',SCHOOL_ADDRESS,'
')"/>
</xsl:for-each>
<xsl:for-each select="STUDENT_DTLS/STUDENT">
<xsl:value-of select="concat('',',','',',',STUDENT_NAME,',',STUDENT_CLASS,'
')"/>
</xsl:for-each>
<xsl:for-each select="SCHOOL_AWARDS/AWARDS">
<xsl:value-of
select="concat('',',','',',','',',','',',',AWARD_NAME,',',AWARD_DATE,'
')"/>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/SCHOOLS">
<!-- header -->
<xsl:text>SCHOOL_NAME,SCHOOL_ADDRESS,STUDENT_NAME,STUDENT_CLASS,AWARD_NAME,AWARD_DATE </xsl:text>
<!-- generate rows -->
<xsl:call-template name="write-rows">
<xsl:with-param name="schools" select="SCHOOL_DATA/SCHOOL"/>
<xsl:with-param name="students" select="SCHOOL_DATA/STUDENT_DTLS/STUDENT"/>
<xsl:with-param name="awards" select="SCHOOL_DATA/SCHOOL_AWARDS/AWARDS"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="write-rows">
<xsl:param name="schools"/>
<xsl:param name="students"/>
<xsl:param name="awards"/>
<xsl:param name="i" select="1"/>
<!-- SCHOOL -->
<xsl:value-of select="$schools[$i]/SCHOOL_NAME"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="$schools[$i]/SCHOOL_ADDRESS"/>
<xsl:text>,</xsl:text>
<!-- STUDENT -->
<xsl:value-of select="$students[$i]/STUDENT_NAME"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="$students[$i]/STUDENT_CLASS"/>
<xsl:text>,</xsl:text>
<!-- AWARD -->
<xsl:value-of select="$awards[$i]/AWARD_NAME"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="$awards[$i]/AWARD_DATE"/>
<xsl:text> </xsl:text>
<!-- recursive call -->
<xsl:if test="$i < count($students) or $i < count($awards)">
<xsl:call-template name="write-rows">
<xsl:with-param name="schools" select="$schools"/>
<xsl:with-param name="students" select="$students"/>
<xsl:with-param name="awards" select="$awards"/>
<xsl:with-param name="i" select="$i + 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>