【发布时间】:2017-06-23 00:14:40
【问题描述】:
我正在尝试将逗号分隔列表转换为具有层次结构的 XML 文件。为此,我单独使用 XSLT,最好使用一次转换。前面有一个类似的例子,但它没有深入创建子元素,我认为这是这种转换过程中的一个常见问题,据我所知一直没有明确的答案。
类似的例子: XSLT 2.0 to convert CSV to XML format
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>
<ImportantDevision>
<ClaimStatus></ClaimStatus>
<ClaimantName></ClaimantName>
</ImportantDivision>
</Claim>
</Claims>
没有子元素的工作 XSLT 2.0 版:
<xsl:param name="inputCsv"/>
<xsl:template match="/" name="csv2xml">
<Claims>
<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>
</Claims>
</xsl:template>
然后我将拥有一个虚拟 XML 文件,以欺骗 XSL 来转换我的 CSV 文件。 也许一个更好的问题是如何在创建标记名称、属性、ID 等之前仅使用 XSLT 来区分各个部分?
【问题讨论】:
-
不确定您的问题到底是什么。您的样式表将连续处理所有单元格。如果您想将其中一些放在包装器元素中,您必须告诉样式表哪些是 - 按名称或按位置。无法从输入中推断出此信息。
-
这里的论文saxonica.com/papers/ideadb-1.1/mhk-paper.xml 讨论了一个类似的问题,它可能会给你一些想法。请注意,使用 XSLT 2.0 不需要 XML 源文档:您可以在命名模板处启动处理。
标签: xml csv xslt xslt-2.0 hierarchy