gpt4 book ai didi

xml - 使用 xslt 样式表将 xml 文档转换为逗号分隔 (CSV) 文件

转载 作者:数据小太阳 更新时间:2023-10-29 02:04:24 30 4
gpt4 key购买 nike

我需要一些帮助,可以使用 xslt 样式表将 xml 文档转换为 CSV 文件。我正在尝试使用以下 xsl,但似乎无法正确使用。我希望我的逗号分隔文件包含列标题,然后是数据。我最大的问题是删除最后一项后的最后一个逗号并插入回车符,以便每组数据显示在单独的行中。我一直在使用 XML 记事本。

  <xsl:template match="/">
<xsl:element name="table">
<xsl:apply-templates select="/*/*[1]" mode="header" />
<xsl:apply-templates select="/*/*" mode="row" />
</xsl:element>
</xsl:template>

<xsl:template match="*" mode="header">
<xsl:element name="tr">
<xsl:apply-templates select="./*" mode="column" />
</xsl:element>
</xsl:template>

<xsl:template match="*" mode="row">
<xsl:element name="tr">
<xsl:apply-templates select="./*" mode="node" />
</xsl:element>
</xsl:template>

<xsl:template match="*" mode="column">
<xsl:element name="th">
<xsl:value-of select="translate(name(.),'qwertyuiopasdfghjklzxcvbnm_','QWERTYUIOPASDFGHJKLZXCVBNM ')" />
</xsl:element>,
</xsl:template>

<xsl:template match="*" mode="node">
<xsl:element name="td">
<xsl:value-of select="." />
</xsl:element>,
</xsl:template>

最佳答案

我将其用于简单的 XSLT 以将 XML 转换为 CSV;它假定根节点的所有子节点都是 CSV 中的行,将根的第一个子节点的元素名称作为字段名称。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>

<xsl:template match="/">
<xsl:for-each select="*/*[1]/*">
<xsl:value-of select="name()" />
<xsl:if test="not(position() = last())">,</xsl:if>
</xsl:for-each>
<xsl:text>&#10;</xsl:text>
<xsl:apply-templates select="*/*" mode="row"/>
</xsl:template>

<xsl:template match="*" mode="row">
<xsl:apply-templates select="*" mode="data" />
<xsl:text>&#10;</xsl:text>
</xsl:template>

<xsl:template match="*" mode="data">
<xsl:choose>
<xsl:when test="contains(text(),',')">
<xsl:text>&quot;</xsl:text>
<xsl:call-template name="doublequotes">
<xsl:with-param name="text" select="text()" />
</xsl:call-template>
<xsl:text>&quot;</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="." />
</xsl:otherwise>
</xsl:choose>
<xsl:if test="position() != last()">,</xsl:if>
</xsl:template>

<xsl:template name="doublequotes">
<xsl:param name="text" />
<xsl:choose>
<xsl:when test="contains($text,'&quot;')">
<xsl:value-of select="concat(substring-before($text,'&quot;'),'&quot;&quot;')" />
<xsl:call-template name="doublequotes">
<xsl:with-param name="text" select="substring-after($text,'&quot;')" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

所以这个 XML:

<csv>
<row>
<field1>foo</field1>
<field2>ba"r</field2>
</row>
<row>
<field1>foo,2</field1>
<field2>bar,"2</field2>
</row>
</csv>

转换为:

field1,field2
foo,ba"r
"foo,2","bar,""2"

不确定这是否有帮助,这取决于您的 XML 布局方式。

编辑:这是一个更彻底的转换:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="field" match="/*/*/*" use="name()" />
<xsl:output method="text"/>

<xsl:template match="/">
<xsl:for-each select="*/*/*[generate-id() = generate-id(key('field',name())[1])]">
<xsl:value-of select="name()" />
<xsl:if test="position() != last()">,</xsl:if>
</xsl:for-each>
<xsl:text>&#10;</xsl:text>
<xsl:apply-templates select="*/*" mode="row"/>
</xsl:template>

<xsl:template match="*" mode="row">
<xsl:variable name="row" select="*" />
<xsl:for-each select="/*/*/*[generate-id() = generate-id(key('field',name())[1])]">
<xsl:variable name="name" select="name()" />
<xsl:apply-templates select="$row[name()=$name]" mode="data" />
<xsl:if test="position() != last()">,</xsl:if>
</xsl:for-each>
<xsl:text>&#10;</xsl:text>
</xsl:template>

<xsl:template match="*" mode="data">
<xsl:choose>
<xsl:when test="contains(text(),',')">
<xsl:text>&quot;</xsl:text>
<xsl:call-template name="doublequotes">
<xsl:with-param name="text" select="text()" />
</xsl:call-template>
<xsl:text>&quot;</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="." />
</xsl:otherwise>
</xsl:choose>
<xsl:if test="position() != last()">,</xsl:if>
</xsl:template>

<xsl:template name="doublequotes">
<xsl:param name="text" />
<xsl:choose>
<xsl:when test="contains($text,'&quot;')">
<xsl:value-of select="concat(substring-before($text,'&quot;'),'&quot;&quot;')" />
<xsl:call-template name="doublequotes">
<xsl:with-param name="text" select="substring-after($text,'&quot;')" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

这将在您的 CSV 中为所有“行”中存在的所有标签名称创建一列,并在每一行中填充相应的列。

关于xml - 使用 xslt 样式表将 xml 文档转换为逗号分隔 (CSV) 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3056579/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com