XML-XSLT-CSV 改造
XML-XSLT-CSV transformation
我正在尝试通过 XSLT 将我的 XML 文档转换为 CSV。目前还没有达到预期的效果。
XML如下:
<projects>
<project>
<name>Shockwave</name>
<language>Ruby</language>
<owner>Brian May</owner>
<state>New</state>
<startDate>31/10/2008 0:00:00</startDate>
</project>
<project>
<name>Other</name>
<language>Erlang</language>
<owner>Takashi Miike</owner>
<state> Canceled </state>
<startDate>07/11/2008 0:00:00</startDate>
</project>
</projects>
XSLT 如下:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="iso-8859-1"/>
<xsl:strip-space elements="*" />
<xsl:template match="/*/child::*">
<xsl:for-each select="child::*">
<xsl:if test="position() != last()">
<xsl:value-of select="normalize-space(.)"/>,
</xsl:if>
<xsl:if test="position() = last()">
<xsl:value-of select="normalize-space(.)"/><xsl:text>
</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
输出如下:
虽然要求转换为 CSV,如下所示:
Header 是第一行。然后在 startDate 之后换行。
姓名、语言、所有者、州、开始日期
Shockwave,Ruby,Brian May,新,2008 年 10 月 31 日 0:00:00
其他,Erlang,Takashi Miike,已取消,07/11/2008 0:00:00
这个语句有问题
<xsl:if test="position() != last()">
<xsl:value-of select="normalize-space(.)"/>,
</xsl:if>
你输出的是逗号,但是逗号后面的换行符也会输出。如果整个文本节点都是空白,XSLT 只会忽略 white-space。一旦包含 non-whitespace 字符,它也会输出缩进!
因此,您需要将其更改为...
<xsl:if test="position() != last()">
<xsl:value-of select="normalize-space(.)"/><xsl:text>,</xsl:text>
</xsl:if>
话虽如此,您可以进一步简化 XSLT。试试这个
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="iso-8859-1"/>
<xsl:strip-space elements="*" />
<xsl:template match="/*/child::*">
<xsl:for-each select="child::*">
<xsl:if test="position() > 1">
<xsl:text>,</xsl:text>
</xsl:if>
<xsl:value-of select="normalize-space(.)"/>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
编辑:如果您想输出 header 行,请将此模板添加到 XSLT
<xsl:template match="/*">
<xsl:for-each select="*[1]/*">
<xsl:if test="position() > 1">
<xsl:text>,</xsl:text>
</xsl:if>
<xsl:value-of select="local-name()"/>
</xsl:for-each>
<xsl:text>
</xsl:text>
<xsl:apply-templates />
</xsl:template>
我正在尝试通过 XSLT 将我的 XML 文档转换为 CSV。目前还没有达到预期的效果。
XML如下:
<projects>
<project>
<name>Shockwave</name>
<language>Ruby</language>
<owner>Brian May</owner>
<state>New</state>
<startDate>31/10/2008 0:00:00</startDate>
</project>
<project>
<name>Other</name>
<language>Erlang</language>
<owner>Takashi Miike</owner>
<state> Canceled </state>
<startDate>07/11/2008 0:00:00</startDate>
</project>
</projects>
XSLT 如下:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="iso-8859-1"/>
<xsl:strip-space elements="*" />
<xsl:template match="/*/child::*">
<xsl:for-each select="child::*">
<xsl:if test="position() != last()">
<xsl:value-of select="normalize-space(.)"/>,
</xsl:if>
<xsl:if test="position() = last()">
<xsl:value-of select="normalize-space(.)"/><xsl:text>
</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
输出如下:
虽然要求转换为 CSV,如下所示: Header 是第一行。然后在 startDate 之后换行。
姓名、语言、所有者、州、开始日期
Shockwave,Ruby,Brian May,新,2008 年 10 月 31 日 0:00:00
其他,Erlang,Takashi Miike,已取消,07/11/2008 0:00:00
这个语句有问题
<xsl:if test="position() != last()">
<xsl:value-of select="normalize-space(.)"/>,
</xsl:if>
你输出的是逗号,但是逗号后面的换行符也会输出。如果整个文本节点都是空白,XSLT 只会忽略 white-space。一旦包含 non-whitespace 字符,它也会输出缩进!
因此,您需要将其更改为...
<xsl:if test="position() != last()">
<xsl:value-of select="normalize-space(.)"/><xsl:text>,</xsl:text>
</xsl:if>
话虽如此,您可以进一步简化 XSLT。试试这个
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="iso-8859-1"/>
<xsl:strip-space elements="*" />
<xsl:template match="/*/child::*">
<xsl:for-each select="child::*">
<xsl:if test="position() > 1">
<xsl:text>,</xsl:text>
</xsl:if>
<xsl:value-of select="normalize-space(.)"/>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
编辑:如果您想输出 header 行,请将此模板添加到 XSLT
<xsl:template match="/*">
<xsl:for-each select="*[1]/*">
<xsl:if test="position() > 1">
<xsl:text>,</xsl:text>
</xsl:if>
<xsl:value-of select="local-name()"/>
</xsl:for-each>
<xsl:text>
</xsl:text>
<xsl:apply-templates />
</xsl:template>