0

I have following XML :

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
    <cd>
        <title>Empire Burlesque</title>
        <artist>Bob Dylan</artist>
        <country>USA</country>
        <company>Columbia</company>
        <price>10</price>
        <year>1985</year>
    </cd>
    <cd>
        <title>Empire Burlesque</title>
        <artist>Bob Dylan</artist>
        <country>USA</country>
        <company>Columbia</company>
        <price>11</price>
        <year>1985</year>
    </cd>
    <catalog>

XSL as follows :

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" />
    <xsl:template match="/">
        {
            "Details": {
                "your_requested_data" : "{\n<xsl:for-each select='catalog/cd' ><xsl:choose><xsl:when test='position() = last()'>\"data\" : [{\"price\":\"<xsl:value-of select='price' />\"}]</xsl:when></xsl:choose></xsl:for-each>}"
            }    
        }
</xsl:template>
</xsl:stylesheet>

Output I need is :

{
            "Details": {
                "your_requested_data" : "{\n \"data\" : [{\"price\":\"10\"},{\"price\":\"11\"}]}"
            }    
}

Basically I am trying to build stringify JSON from XML using XSLT.

Please suggest how to achieve it.

1 Answers1

0

In XSLT 3 (as supported by Saxon 9.8 or later or SaxonJS 2) you could use

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="3.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="#all">
  
  <xsl:output method="json" indent="no"/>

  <xsl:template match="/" name="xsl:initial-template">
    <xsl:sequence
      select="map { 'details' : map { 'yourRequestedData' : serialize(map { 'data' : array { catalog/cd/price ! map { 'price' : number(.) } } }, map { 'method' : 'json' }) }}"/>
  </xsl:template>
  
</xsl:stylesheet>

Sample online fiddle.

Note that I have intentionally used the JSON and XPath number/xs:double data type for the price values instead of a string; if you really want a JSON string use e.g. map { 'price' : string(.) } instead of the used map { 'price' : number(.) }.

Martin Honnen
  • 160,499
  • 6
  • 90
  • 110
  • Thanks for answer, can you also help how to add more nodes ? like `{ "Details": { "your_requested_data" : "{\n \"data\" : [{\"price\":\"10\"},{\"price\":\"11\"}], /"moreNode/": "abc"}" } }` – chandan vishwakarma Jul 13 '23 at 06:18
  • See a tutorial on XPath 3.1 maps https://www.altova.com/training/xpath3/xpath-31#maps – Martin Honnen Jul 13 '23 at 07:18