'Output multiple elements as a JSON array in XSLT

I have an XSL Code as shown below.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" />

  <xsl:variable name="inlineAddressArray">
    <addrline>Home1</addrline>
    <addrline>Home2</addrline>
    <addrline>Home3</addrline>
  </xsl:variable>

  <xsl:variable xmlns:exsl="http://exslt.org/common" name="data" select="exsl:node-set($inlineAddreddArray)" />

  <addressLines>
    <xsl:value-of select="$data/addrline" />
  </addressLines>

</xsl:stylesheet>

My expected JSON output should be:

"addressLines":"[Home1,Home2,Home3]"

Output that I'm getting

"addressLines": "Home1Home2Home3"

Basically it is just concatenating every element as a single element.

But, I should get three elements separately as shown above.

Can anyone please help me on this? Don't mind if it's a silly query. I'm very new to XSLT :)



Solution 1:[1]

No need for Newtonsoft.Json.JsonConvert.SerializeXmlNode() .

Given this xml:

<inlineAddressArray>
  <addrline>Home1</addrline>
  <addrline>Home2</addrline>
  <addrline>Home3</addrline>
</inlineAddressArray>

Using this xslt 2.0:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output method="text"  encoding="UTF-8" />
  
  <xsl:template match="inlineAddressArray">
    <xsl:text>"addressLines":"[</xsl:text>
    <xsl:value-of select="addrline" separator=","/>
    <xsl:text>]"</xsl:text>
  </xsl:template>
  
</xsl:stylesheet>

or using xslt 1.0

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="text"  encoding="UTF-8" />
  
  <xsl:template match="inlineAddressArray">
    <xsl:text>"addressLines":"[</xsl:text>
    <xsl:apply-templates select="addrline"/>
    <xsl:text>]"</xsl:text>
  </xsl:template>
  
  <xsl:template match="addrline">
    <xsl:value-of select="."/>
    <xsl:if test="not(position()=last())">
      <xsl:text>,</xsl:text>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

results in this :

"addressLines":"[Home1,Home2,Home3]"

UPDATE

if you also want to deal with empty addrline like i.e.

<inlineAddressArray>
  <addrline>Home1</addrline>
  <addrline>Home2</addrline>
  <addrline></addrline>
</inlineAddressArray>

Your xslt 1.0 could look like this:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="text"  encoding="UTF-8" />
  
  <xsl:template match="inlineAddressArray">
    <xsl:text>"addressLines":"[</xsl:text>
    <xsl:apply-templates select="addrline"/>
    <xsl:text>]"</xsl:text>
  </xsl:template>
  
  <xsl:template match="addrline">
    <xsl:value-of select="."/>
    <xsl:if test=" following-sibling::addrline[(normalize-space(.))]">
      <xsl:text>,</xsl:text>
    </xsl:if>
  </xsl:template>

  <xsl:template match="addrline[not(normalize-space(.))]"/>

</xsl:stylesheet>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1