xml - 通过 XSLT 将 .txt 文件转换为 JSON
问题描述
我有以下 .txt 文件,其中包含示例数据,例如:
january,february,march
1,2,3
我使用以下代码首先将 .txt 文件转换为 XML,然后将其转换为 JSON。
XML 转换为我提供了以下输出:
<Sales>
<Month>
<january>1</january>
<february>2</february>
<march>3</march>
</Month>
</Sales>
我正在尝试以以下格式以 JSON 格式输出此输出:
{
"Month": [
{
"january": "1",
"february": "2",
"march": "3"
}
}
我正在使用的代码如下,在 XML 部分之前都可以,但在 JSON 转换部分之前没有。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:exslt="http://exslt.org/common" extension-element-prefixes="exsl"
xmlns:exsl="http://exslt.org/common" xmlns:fcn="http://www.re.com/2018/local-functions"
exclude-result-prefixes="xs fn fcn exsl" version="3.0">
<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="'/Users/user/Desktop/so.csv'"/>
<xsl:template match="/" name="csv2xml">
<Sales>
<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)">
<Month>
<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>
</Month>
</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>
</Sales>
<xsl:variable name="transformed-xml">
<array xmlns="http://www.w3.org/2005/xpath-functions">
<xsl:for-each select="Month">
<map>
<string key="id">
<xsl:value-of select="./january" />
</string>
</map>
</xsl:for-each>
</array>
</xsl:variable>
<xsl:value-of select="xml-to-json($transformed-xml, map {'indent': true()})" />
</xsl:template>
</xsl:stylesheet>
解决方案
对于将您创建的 XML 转换为您可以提供的 XML 表示形式,xml-to-json
我建议采用类似的方法
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns="http://www.w3.org/2005/xpath-functions"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:variable name="xml-rep-of-json">
<xsl:apply-templates/>
</xsl:variable>
<xsl:value-of select="xml-to-json($xml-rep-of-json, map { 'indent' : true() })"/>
</xsl:template>
<xsl:template match="Sales">
<array>
<xsl:apply-templates/>
</array>
</xsl:template>
<xsl:template match="Month">
<map>
<xsl:apply-templates/>
</map>
</xsl:template>
<xsl:template match="Month/*" expand-text="yes">
<string key="{local-name()}">{.}</string>
</xsl:template>
</xsl:stylesheet>
在 JSON 方面,它创建了一个顶级数组,其中包含未命名的 JSON 对象/映射,其中包含包含数据的命名字符串属性,例如
[
{ "january" : "1",
"february" : "2",
"march" : "3" },
{ "january" : "1",
"february" : "2",
"march" : "3" } ]
https://xsltfiddle.liberty-development.net/ej9EGdp/2
要将其与将 CSV 数据转换为 XML 的第一步相结合,您可以使用
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns="http://www.w3.org/2005/xpath-functions"
exclude-result-prefixes="#all"
version="3.0">
<xsl:param name="csv-string" as="xs:string">january,february,march
1,2,3
1,2,3
1,2,3
</xsl:param>
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:variable name="csv-data-as-xml">
<Sales xmlns="">
<xsl:variable name="csv" select="$csv-string"/>
<!--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)">
<Month>
<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>
</Month>
</xsl:if>
</xsl:non-matching-substring>
</xsl:analyze-string>
</Sales>
</xsl:variable>
<xsl:variable name="xml-rep-of-json">
<xsl:apply-templates select="$csv-data-as-xml/node()"/>
</xsl:variable>
<xsl:value-of select="xml-to-json($xml-rep-of-json, map { 'indent' : true() })"/>
</xsl:template>
<xsl:template match="Sales">
<array>
<xsl:apply-templates/>
</array>
</xsl:template>
<xsl:template match="Month">
<map>
<xsl:apply-templates/>
</map>
</xsl:template>
<xsl:template match="Month/*" expand-text="yes">
<string key="{local-name()}">{.}</string>
</xsl:template>
</xsl:stylesheet>
推荐阅读
- geoip - MaxMind GeoIP 城市状态精度
- scichart - SciChart TimeSpanAxis 不显示 VerticalLineAnnotation
- visual-studio-2017 - Azure ARM DSC - 安装 VS2017 远程调试器
- google-chrome-extension - 如何使用 chrome.webRequest API 更改 http 方法
- javascript - 如何在角度管道中传递变量
- triggers - Salesforce 比较标准 obj 和自定义对象并分配值
- java - Dependent dynamic dropdown using JSP, Servlet, JQuery and denormalized Mysql table
- java - 单击时尝试获取 JButton 的坐标
- java - Draw jpanel at double position
- batch-file - 当字符串与定界符具有相同字符时如何仅处理特定定界符