我正在创建和使用XSLT文件将XML文件中的某些数据显示为CSV。 我坚持一个特定的方面,因为我找不到许多具有类似xml结构的在线示例。
鉴于这个假设的XML:
<collection>
<book>
<author> author1name </author>
<author> author2name </author>
<title> booktitle </title>
</book>
<book>
<author> authorname </author>
<title> booktitle </title>
</book>
</collection>
和xslt:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" >
<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
<xsl:template match="/">
author,title
<xsl:for-each select="//book">
<xsl:value-of select="concat
(author,',',title',','
')"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
其中输出
author, title
author1name, booktitle
authorname, booktitle
请注意,输出中不包含author2。这是一个很大的数据丢失。 我试图使用嵌套的for循环来遍历所有作者,但我已经计算了太多的错误。
有人可以提出一种方法来产生
的输出author1name;author2name, booktitle
第一本书? (两位作者用分号分隔)
感谢您的帮助。
答案 0 :(得分:2)
您可以做的是创建一个匹配author
的模板,您只需输出名称,如果不是第一作者,则在其前面加分号
<xsl:template match="author">
<xsl:if test="position() > 1">;</xsl:if>
<xsl:value-of select="." />
</xsl:template>
然后,要输出每本书,而不是将author
放在concat语句中,请改用xsl:apply-templates
<xsl:apply-templates select="author" />
<xsl:value-of select="concat(',', title,'
')"/>
试试这个XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
<xsl:template match="collection">
<xsl:text>author,title</xsl:text>
<xsl:value-of select="'
'" />
<xsl:apply-templates select="book"/>
</xsl:template>
<xsl:template match="book">
<xsl:apply-templates select="author"/>
<xsl:value-of select="concat(',', title,'
')"/>
</xsl:template>
<xsl:template match="author">
<xsl:if test="position() > 1">;</xsl:if>
<xsl:value-of select="."/>
</xsl:template>
</xsl:stylesheet>
编辑:顺便说一下,将来,如果您能够使用XSLT 2.0,您可以使用separator
运算符的xsl:value-of
属性来实现相同的结果:
<xsl:value-of select="author" separator=";" />
答案 1 :(得分:0)
concat()是一个字符串函数;您无法将其应用于节点集。请尝试改为:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="/">
<xsl:text>author,title </xsl:text>
<xsl:for-each select="collection/book">
<xsl:for-each select="author">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">
<xsl:text>;</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text>,</xsl:text>
<xsl:value-of select="title"/>
<xsl:if test="position()!=last()">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>