我正在处理以下XML文档,我想将XML转换为JSON。
<?xml version="1.0" encoding="UTF-8"?>
<DATA>
<CATEGORY>
<COUNT> 5 </COUNT>
</CATEGORY>
<TYPE>
<COUNT> 10 </COUNT>
</TYPE>
<FRUITS>
<NAME>APPLE</NAME>
<FRUIT_COUNT>10</FRUIT_COUNT>
</FRUITS>
<FRUITS>
<NAME>ORANGES</NAME>
<FRUIT_COUNT>20</FRUIT_COUNT>
</FRUITS>
</DATA>
我想将上述XML转换为JSON,如下所示。
{
"CATEGORY":5,
"TYPE": 10,
"FRUITS":{
"APPLE": 10,
"ORANGES": 20
}
}
所以我写了下面的XSLT代码,将上面的XML转换为JSON。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text"/>
<xsl:template match="/DATA">
<xsl:text>{"CATEGORY":</xsl:text>
<xsl:value-of select="CATEGORY/COUNT"/>
<xsl:text>,</xsl:text>
<xsl:text>"TYPE":</xsl:text>
<xsl:value-of select="TYPE/COUNT"/>
<xsl:text>,</xsl:text>
<xsl:text>
"FRUITS": {
</xsl:text>
<xsl:for-each select="FRUITS">
<xsl:text>"</xsl:text>
<xsl:value-of select="NAME"/>
<xsl:text>":</xsl:text>
<xsl:value-of select="FRUIT_COUNT"/>
<xsl:if test="position()!=last()">,</xsl:if>
</xsl:for-each>
<xsl:text>}}</xsl:text>
</xsl:template>
</xsl:stylesheet>
上述XSLT正在按预期将XML转换为JSON。但是,我无法概括上述XSLT,因此,如果添加了新字段,则不必像在上述XSLT中那样对它进行硬编码。推广XSLT以便不进行硬编码即可创建JSON的正确方法是什么?在概括它时我做错了什么?
更新:
我尝试使用以下XSLT来概括XSLT,以将XML转换为JSON:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text"/>
<xsl:template match="/DATA">
<xsl:text>{</xsl:text>
<xsl:for-each select="/DATA">
<xsl:for-each select="*">
<xsl:text>"</xsl:text><xsl:value-of select="local-name()"/><xsl:text>":</xsl:text><xsl:value-of select="."/>
<xsl:if test="position()!=last()">,</xsl:if>
</xsl:for-each>
</xsl:for-each>
<xsl:text>}</xsl:text>
</xsl:template>
</xsl:stylesheet>
但是当我使用上面的XSLT时,输出如下:
{"CATEGORY":
5
,"TYPE":
10
,"FRUITS":
APPLE
10
,"FRUITS":
ORANGES
20
}
如何泛化嵌套的JSON,以便可以正确的格式获取JSON。在修改后的转换后的JSON中,我两次获得“水果”,并且它不是我想要实现的嵌套格式。
答案 0 :(得分:0)
确实没有正确的方法可以概括这一点。您可能需要提出一组要实施的规则,并以此为基础。
DATA
的子元素没有NAME
,则将元素作为属性输出,并以元素名称命名,并将文本值作为其值。NAME
,则输出具有元素名称名称的单个属性,对于具有相同名称的所有元素,输出基于NAME
的嵌套属性。 / li>
在这种情况下,您可以这样编写XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text"/>
<xsl:template match="DATA" priority="2">
<xsl:text>{</xsl:text>
<xsl:apply-templates />
<xsl:text>}</xsl:text>
</xsl:template>
<xsl:template match="*[not(NAME)]">
<xsl:text>"</xsl:text>
<xsl:value-of select="name()" />
<xsl:text>":</xsl:text>
<xsl:value-of select="normalize-space()"/>
<xsl:text>,</xsl:text>
</xsl:template>
<xsl:template match="*[NAME][1]">
<xsl:text>"</xsl:text>
<xsl:value-of select="name()" />
<xsl:text>": {</xsl:text>
<xsl:for-each select="../*[name() = name(current())]">
<xsl:text>"</xsl:text>
<xsl:value-of select="NAME"/>
<xsl:text>":</xsl:text>
<xsl:value-of select="*[not(self::NAME)]"/>
<xsl:if test="position()!=last()">,</xsl:if>
</xsl:for-each>
<xsl:text>}</xsl:text>
</xsl:template>
<xsl:template match="*[NAME][position() > 1]" />
</xsl:stylesheet>