使用 XSLT 在文本文件 (CSV) 中解析 XML 文件
Posted
技术标签:
【中文标题】使用 XSLT 在文本文件 (CSV) 中解析 XML 文件【英文标题】:XML file Parsing in text file (CSV) using XSLT 【发布时间】:2020-04-13 14:12:31 【问题描述】:尝试使用 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>
【问题讨论】:
您的预期输出将一等奖与一等学生相关联,二等奖与二等学生相关联。我在源 XML 中没有看到这样的关联。请澄清这里需要应用的逻辑。 【参考方案1】:如果(看起来)您只想在第 1 列和第 2 列中列出所有学校,在第 3 和第 4 列中列出所有学生,在第 5 和第 6 列中列出所有奖项,但两者之间没有联系三个列表,然后尝试:
XSLT 1.0
<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>
【讨论】:
以上是关于使用 XSLT 在文本文件 (CSV) 中解析 XML 文件的主要内容,如果未能解决你的问题,请参考以下文章