I have an XML input with elements that have a number of attributes named "stats".
I'd like to create just one attribute element "stats" for each of the existing attributes and put it in JSON as one key.
Input:
<STATS>
<CODE>Apple</CODE><COUNT>4</COUNT>
</STATS>
<STATS>
<CODE>Orange</CODE><COUNT>1876</COUNT>
</STATS>
<STATS>
<CODE>Kiwi</CODE><COUNT>9</COUNT>
</STATS>
Output:
"STATS":{
"Apple":4,
"Orange":1876,
"Kiwi": 9
}
UPDATE: I've tried this XSL
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">{
<xsl:apply-templates select="*"/>}
</xsl:template>
<!-- Object or Element Property-->
<xsl:template match="*">
"<xsl:value-of select="name()"/>" :<xsl:call-template name="Properties">
<xsl:with-param name="parent" select="'Yes'"> </xsl:with-param>
</xsl:call-template>
</xsl:template>
<!-- Array Element -->
<xsl:template match="*" mode="ArrayElement">
<xsl:call-template name="Properties"/>
</xsl:template>
<!-- Object Properties -->
<xsl:template name="Properties">
<xsl:param name="parent"></xsl:param>
<xsl:variable name="childName" select="name(*[1])"/>
<xsl:choose>
<xsl:when test="not(*|@*)"><xsl:choose><xsl:when test="$parent='Yes'"> <xsl:text>"</xsl:text><xsl:value-of select="."/><xsl:text>"</xsl:text></xsl:when>
<xsl:otherwise>"<xsl:value-of select="name()"/>":"<xsl:value-of select="."/>"</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="count(*[name()=$childName]) > 1">{ "<xsl:value-of select="$childName"/>" :[<xsl:apply-templates select="*" mode="ArrayElement"/>] }</xsl:when>
<xsl:otherwise>{
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="*"/>
}</xsl:otherwise>
</xsl:choose>
<xsl:if test="following-sibling::*">,</xsl:if>
</xsl:template>
<!-- Attribute Property -->
<xsl:template match="@*">"<xsl:value-of select="name()"/>" : "<xsl:value-of select="."/>",
</xsl:template>
</xsl:stylesheet>
But this doesn't work, it seems. It is giving me the following output:
"STATS" :{
"CODE" :"Apple",
"COUNT" :"4"
},
"STATS" :{
"CODE" :"Orange",
"COUNT" :"1876"
},
"STATS" :{
"CODE" :"Kiwi",
"COUNT" :"9"
}
What's the right way to do this?
Given a well-formed (!) input such as:
XML
<root>
<STATS>
<CODE>Apple</CODE>
<COUNT>4</COUNT>
</STATS>
<STATS>
<CODE>Orange</CODE>
<COUNT>1876</COUNT>
</STATS>
<STATS>
<CODE>Kiwi</CODE>
<COUNT>9</COUNT>
</STATS>
</root>
the following stylesheet:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="utf-8"/>
<xsl:template match="/root">
<xsl:text>"STATS":{</xsl:text>
<xsl:for-each select="STATS">
<xsl:text>"</xsl:text>
<xsl:value-of select="CODE"/>
<xsl:text>":</xsl:text>
<xsl:value-of select="COUNT"/>
<xsl:if test="position()!=last()">,</xsl:if>
</xsl:for-each>
<xsl:text>}</xsl:text>
</xsl:template>
</xsl:stylesheet>
wil return:
Result
"STATS":{"Apple":4,"Orange":1876,"Kiwi":9}
One possibility to achieve this JSON output is the following XSLT-1.0 code. It does assume that your input XML is wrapped in an element named root
to make it well-formed .
So the input XML file looks like this:
<?xml version="1.0" encoding="UTF-8" ?>
<root>
<STATS>
<CODE>Apple</CODE><COUNT>4</COUNT>
</STATS>
<STATS>
<CODE>Orange</CODE><COUNT>1876</COUNT>
</STATS>
<STATS>
<CODE>Kiwi</CODE><COUNT>9</COUNT>
</STATS>
</root>
The XSLT-1.0 file satisfying your needs looks like this:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/root">
<xsl:text>STATS: {
</xsl:text>
<xsl:apply-templates select="STATS" />
<xsl:text>
}</xsl:text>
</xsl:template>
<!-- STATS elements -->
<xsl:template match="STATS">
<xsl:text> "</xsl:text><xsl:value-of select="CODE"/><xsl:text>": </xsl:text>
<xsl:value-of select="COUNT"/>
<xsl:if test="position() != last()"><xsl:text>,
</xsl:text></xsl:if>
</xsl:template>
</xsl:stylesheet>
Its output is:
STATS: {
"Apple": 4,
"Orange": 1876,
"Kiwi": 9
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.