使用 XML 从 XML 转换为 CSV 时 CSV 文件中的标题
Posted
技术标签:
【中文标题】使用 XML 从 XML 转换为 CSV 时 CSV 文件中的标题【英文标题】:Title in CSV file when converting from XML to CSV using XML 【发布时间】:2019-10-15 04:44:43 【问题描述】:我正在尝试使用 XSLT 将 XML 转换为 CSV,我正在获取记录,但我需要 CSV 文件中的标题。
例如:
Name EmailAddress
Gaurav Gaur@yopmail.com
Satya Satya@yopmail.com
XML
<?xml version="1.0"?>
<SearchResults>
<Columns>
<Column Label="Name">Name</Column>
<Column Label="Email Addresses">EmailAddress</Column>
</Columns>
<Rows>
<Row>
<Name>Gaurav Joshi</Name>
<EmailAddress>ybenipohe-3888@yopmail.com</EmailAddress>
</Row>
<Row>
<Name>Satya</Name>
<EmailAddress>eqaddoxoqu-8703@yopmail.com</EmailAddress>
</Row>
XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<!-- This transform is used to generate a CSV file.-->
<xsl:output method="text" indent="no" />
<xsl:template match="/">
<xsl:apply-templates select="/SearchResults/Rows/Row" />
</xsl:template>
<xsl:template match="/SearchResults/Rows/Row">
<xsl:text>"</xsl:text>
<xsl:value-of select="position()" />
<xsl:text>"</xsl:text>
<xsl:for-each select="*">
<xsl:text>,"</xsl:text>
<xsl:value-of select="." />
<xsl:text>"</xsl:text>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="/SearchResults/Columns" />
</xsl:stylesheet>
【问题讨论】:
【参考方案1】:您当前有一个匹配/SearchResults/Columns
的模板,这实际上是多余的,因为您没有任何模板明确选择这些(由于您在使用<xsl:apply-templates select="/SearchResults/Rows/Row" />
)。
但是你可以很容易地调整它来输出标题,然后你只需要一个xsl:apply-templates
来选择它。
试试这个 XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<!-- This transform is used to generate a CSV file.-->
<xsl:output method="text" indent="no" />
<xsl:template match="/">
<xsl:apply-templates select="/SearchResults/Columns" />
<xsl:apply-templates select="/SearchResults/Rows/Row" />
</xsl:template>
<xsl:template match="Row">
<xsl:text>"</xsl:text>
<xsl:value-of select="position()" />
<xsl:text>"</xsl:text>
<xsl:for-each select="*">
<xsl:text>,"</xsl:text>
<xsl:value-of select="." />
<xsl:text>"</xsl:text>
</xsl:for-each>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="Columns">
<xsl:text>"Row"</xsl:text>
<xsl:for-each select="Column">
<xsl:text>,"</xsl:text>
<xsl:value-of select="@Label" />
<xsl:text>"</xsl:text>
</xsl:for-each>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
但这使得(大?)假设每个Row
的子节点与相关Column
节点的顺序相同。如果不是这种情况,你有工作要做。尝试用这个替换匹配Row
的模板
<xsl:template match="Row">
<xsl:text>"</xsl:text>
<xsl:value-of select="position()" />
<xsl:text>"</xsl:text>
<xsl:variable name="Row" select="." />
<xsl:for-each select="/SearchResults/Columns/Column">
<xsl:text>,"</xsl:text>
<xsl:value-of select="$Row/*[name() = current()]" />
<xsl:text>"</xsl:text>
</xsl:for-each>
<xsl:text> </xsl:text>
</xsl:template>
【讨论】:
以上是关于使用 XML 从 XML 转换为 CSV 时 CSV 文件中的标题的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法使用 KnockoutJS 将 XML 文件转换为 CSV?