【问题标题】:XSLT 2.0 to convert CSV to XML formatXSLT 2.0 将 CSV 转换为 XML 格式
【发布时间】:2015-03-27 07:27:14
【问题描述】:

我正在尝试将 CSV(逗号分隔文件)转换为 XML。为此,我正在编写一个 XSLT 模板,这是我第一次尝试 XSLT...

CSV 样本:

ClaimRef,HandlerRef,ClaimType,Date,Area,SettleDate,ClaimStatus,ClaimantName
1,1/1,Liability,08-12-2013,US,23-05-2014,Closed,Mark
2,1/2,Liability,08-10-2013,UK,23-02-2014,Closed,John

所需的 XML 输出格式:

 <Claims>
     <Claim>
      <ClaimRef></ClaimRef>
      <HandlerRef></HandlerRef>
      <ClaimType></ClaimType>
      <Date></Date>
      <Area></Area>
      <SettleDate></SettleDate>
      <ClaimStatus></ClaimStatus>
      <ClaimantName></ClaimantName>
     </Claim>
    </Claims>

我使用http://blogs.msdn.com/b/kaevans/archive/2003/04/17/5780.aspx 作为初始启动并使用http://xslttest.appspot.com/ 来测试结果。但是这篇文章提到了如何获取&lt;row&gt;&lt;elem&gt;, etc的值。

请您指导我如何编写 XSLT 代码以根据示例 CSV 数据生成上述 XML。

【问题讨论】:

标签: xml csv xslt


【解决方案1】:

这是一个 XSLT 2.0 选项...

CSV 输入(so.csv 在csv-uri 参数中引用。)

ClaimRef,HandlerRef,ClaimType,Date,Area,SettleDate,ClaimStatus,ClaimantName
1,1/1,Liability,08-12-2013,US,23-05-2014,Closed,Mark
2,1/2,Liability,08-10-2013,UK,23-02-2014,Closed,John

XSLT 2.0(使用格式良好的虚拟 XML 文档或样式表本身作为输入,或指定 csv2xml 作为初始模板。)

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:param name="csv-encoding" as="xs:string" select="'iso-8859-1'"/>
    <xsl:param name="csv-uri" as="xs:string" select="'file:///C:/Users/dhaley/Desktop/so.csv'"/>

    <xsl:template match="/" name="csv2xml">
        <Claims>
            <xsl:choose>
                <xsl:when test="unparsed-text-available($csv-uri, $csv-encoding)">
                    <xsl:variable name="csv" select="unparsed-text($csv-uri, $csv-encoding)"/>
                    <!--Get Header-->
                    <xsl:variable name="header-tokens" as="xs:string*">
                        <xsl:analyze-string select="$csv" regex="\r\n?|\n">
                            <xsl:non-matching-substring>
                                <xsl:if test="position()=1">
                                    <xsl:copy-of select="tokenize(.,',')"/>                                        
                                </xsl:if>
                            </xsl:non-matching-substring>
                        </xsl:analyze-string>
                    </xsl:variable>                    
                    <xsl:analyze-string select="$csv" regex="\r\n?|\n">
                        <xsl:non-matching-substring>
                            <xsl:if test="not(position()=1)">
                                <Claim>
                                    <xsl:for-each select="tokenize(.,',')">
                                        <xsl:variable name="pos" select="position()"/>
                                        <xsl:element name="{$header-tokens[$pos]}">
                                            <xsl:value-of select="."/>
                                        </xsl:element>
                                    </xsl:for-each>
                                </Claim>
                            </xsl:if>
                        </xsl:non-matching-substring>
                    </xsl:analyze-string>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:variable name="error">
                        <xsl:text>Error reading "</xsl:text>
                        <xsl:value-of select="$csv-uri"/>
                        <xsl:text>" (encoding "</xsl:text>
                        <xsl:value-of select="$csv-encoding"/>
                        <xsl:text>").</xsl:text>
                    </xsl:variable>
                    <xsl:message><xsl:value-of select="$error"/></xsl:message>
                    <xsl:value-of select="$error"/>
                </xsl:otherwise>
            </xsl:choose>
        </Claims>
    </xsl:template>

</xsl:stylesheet>

XML 输出

<Claims>
   <Claim>
      <ClaimRef>1</ClaimRef>
      <HandlerRef>1/1</HandlerRef>
      <ClaimType>Liability</ClaimType>
      <Date>08-12-2013</Date>
      <Area>US</Area>
      <SettleDate>23-05-2014</SettleDate>
      <ClaimStatus>Closed</ClaimStatus>
      <ClaimantName>Mark</ClaimantName>
   </Claim>
   <Claim>
      <ClaimRef>2</ClaimRef>
      <HandlerRef>1/2</HandlerRef>
      <ClaimType>Liability</ClaimType>
      <Date>08-10-2013</Date>
      <Area>UK</Area>
      <SettleDate>23-02-2014</SettleDate>
      <ClaimStatus>Closed</ClaimStatus>
      <ClaimantName>John</ClaimantName>
   </Claim>
</Claims>

根据评论更新...

这是相同的示例,但使用变量而不是外部 CSV 文件。您可以使用此 XSLT 在其他支持 XSLT 2.0 的在线测试工具中进行测试。

Example on xsltransform.net

【讨论】:

  • @variable - 我没有任何参考文章。如果您有任何问题或希望我就特定答案添加任何其他详细信息,请告诉我。
  • @variable - 哦,我明白了。我的回答是针对外部 .csv 文件的。要在没有外部文件的情况下进行测试,您可以添加一个变量并删除与unparsed-text() 相关的所有内容。我会更新我的答案。
  • @Tomalak - 是的,XSLT 的主要目标是处理 XML,但是对于诸如 unparsed-text() 之类的函数,您不仅限于处理 XML。当您的目标输出是 XML 时,这非常方便。
  • @variable - 看起来他们的 XSLT 正在寻找一个名为 ROOT 的根元素,这是我的建议;将您的 CSV 包装在根元素中。更新示例:xsltransform.net/eiZQaFu/1
  • @JRSofty - 我认为这可能是最初在 xsltransform.net 链接中的内容:xsltfiddle.liberty-development.net/pPzifpx
猜你喜欢
  • 2013-05-22
  • 2022-11-30
  • 2022-01-05
  • 2011-06-25
  • 2023-04-09
  • 1970-01-01
  • 1970-01-01
  • 2019-02-02
  • 2014-07-20
相关资源
最近更新 更多