当前位置: 首页 > 面试题库 >

用于将XML转换为CSV的XSL:基于数据字段在行尾添加引号

郎玮
2023-03-14
问题内容

我正在尝试使用Java代码将XML文件动态转换为CSV文件。我能够获取转换为CSV的数据,但是问题是我的数据包含“”和“,”。

这是我的示例XML:

<record>
<column name="ID">537316</column>
<column name="TYPE">MANUAL</column>
<column name="SECONDID">546</column>
<column name="INFO">"THIS","IS",FOR,"TEST"</column>
<column name="KEY">345</column>
</record>

这是Java代码:

import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.w3c.dom.Document;

class xmltocsv {

public static void main(String args[]) throws Exception {
    File stylesheet = new File("C:/testxsl.xsl");
    File xmlSource = new File("C:/test.xml");

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document document = builder.parse(xmlSource);

    StreamSource stylesource = new StreamSource(stylesheet);
    Transformer transformer = TransformerFactory.newInstance()
        .newTransformer(stylesource);
    Source source = new DOMSource(document);
    Result outputTarget = new StreamResult(new File("c:/output.csv"));
    transformer.transform(source, outputTarget);
}
}

这是我的XSL文件:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/*">
<xsl:for-each select="*[1]/*">
<xsl:text>"</xsl:text>
<xsl:value-of select="@name"/>
<xsl:text>"</xsl:text>
<xsl:if test="position() != last()">,</xsl:if>
<xsl:if test="position() = last()">
<xsl:text>&#xD;</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:template>
<xsl:output method="text" encoding="iso-8859-1"/>
<xsl:param name="fieldNames" select="'yes'" />
<xsl:strip-space elements="*" />
<xsl:template match="/*/child::*">
<xsl:for-each select="child::*">
<xsl:if test="position() != last()"><xsl:text>"</xsl:text><xsl:value-of  Select="normalize-space(.)"/><xsl:text>"</xsl:text>,</xsl:if>
<xsl:if test="position() = last()"><xsl:text>"</xsl:text><xsl:value-of select="normalize-space(.)"/><xsl:text>"</xsl:text><xsl:text>&#xD;</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

样本输出应为:

ID,TYPE,SECONDID,INFO,KEY
"537316","MANUAL","546","THIS"",""IS"",FOR,""TEST""","345"

但是我得到的输出是:

ID,TYPE,SECONDID,INFO,KEY\n
"537316","MANUAL","546",""THIS","IS",FOR,"TEST"","345"

我使用的XML来自数据库,并且包含特殊字符(“),这会在输出CSV中导致意外结果(当我使用MS
Excel打开输出CSV时)。我需要验证数据是否为引号以及是否存在引号必须添加额外的引号以获得所需的输出。有人可以帮助我解决我可以在XSL中使用的if条件来验证字符串并在数据中搜索(“”)。


问题答案:

以下样式表:

XSLT 1.0

<?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" encoding="utf-8"/>

<xsl:template match="/">
    <xsl:text>ID,TYPE,SECONDID,INFO,KEY&#10;</xsl:text>
    <xsl:for-each select="record/column">
        <xsl:text>"</xsl:text>
        <xsl:call-template name="substitute">
            <xsl:with-param name="text" select="."/>
        </xsl:call-template>
        <xsl:text>"</xsl:text>
        <xsl:if test="position()!=last()">
            <xsl:text>,</xsl:text>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

<xsl:template name="substitute">
    <xsl:param name="text"/>
    <xsl:param name="searchString">"</xsl:param>
    <xsl:param name="replaceString">""</xsl:param>
    <xsl:choose>
        <xsl:when test="contains($text,$searchString)">
            <xsl:value-of select="substring-before($text,$searchString)"/>
            <xsl:value-of select="$replaceString"/>
            <xsl:call-template name="substitute">
                <xsl:with-param name="text" select="substring-after($text,$searchString)"/>
                <xsl:with-param name="searchString" select="$searchString"/>
                <xsl:with-param name="replaceString" select="$replaceString"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$text"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>

当应用于示例输入时,将产生以下输出:

ID,TYPE,SECONDID,INFO,KEY
"537316","MANUAL","546","""THIS"",""IS"",FOR,""TEST""","345"

我相信这是CSV格式的输入数据的正确表示形式。



 类似资料:
  • 问题内容: 我尝试不使用任何xml。 像这样一个:转换为@Bean 问题在这里。 尝试将“ com.cloudlb.domain.User”转换为Class []无效。 错误:投放问题。 先感谢您。 问题答案:

  • 问题内容: 输入XML 输出Json 如何编写通用的xslt样式表,它将输入的xml转换为json 输入可能在根目录下有太多结果,在结果下可能有系统和名称,在系统下还有ID名称和值。 问题答案: 我从此处复制并粘贴的以下XSLT 应该可以帮助您将XML转换为JSON。谢谢 :)

  • 问题内容: 我在使用Python将XML文件转换为CSV时遇到很多麻烦。我看过很多论坛,都尝试过lxml和xmlutils.xml2csv,但是我无法使其正常工作。这是来自Garmin GPS设备的GPS数据。 这是我的XML文件的样子,当然是缩短了: 我的大型XML文件中有几个trk标记,但我可以设法将它们分开-它们代表GPS设备上的不同“段”或行程。我想要的只是一个CSV文件,它绘制了以下内容

  • 问题内容: 我有一组CSV数据要转换为XML。代码看起来不错,但是输出不够完美。它忽略了一些列,因为它们没有值,并且产生了很长的XML数据行,而不是破坏它。 这是我的CSV数据示例: 而我的代码: 当对以上数据执行此代码时,将产生: 我本人以这种形式安排它,但是输出结果很长。产生的输出应为: 问题答案: 我同意Kennet。 我只是添加了 这在元素之间添加了新行,并允许缩进。 更新 首先,我们要介

  • 问题内容: 按照目前的情况,这个问题不适合我们的问答形式。我们希望答案会得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意调查或扩展讨论。如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 7年前关闭。 什么是将XML字符串转换为JSON的最佳javascript函数/插件/库。 我发现该工具:http : //www.thomasfrank.se/xml_t

  • 本文向大家介绍Python将xml和xsl转换为html的方法,包括了Python将xml和xsl转换为html的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Python将xml和xsl转换为html的方法。分享给大家供大家参考。具体分析如下: 这里需要用libxml2,所以还要先安装了libxml2模块才能使用。代码如下: 希望本文所述对大家的Python程序设计有所帮助。