Search code examples
jsonxsltxslt-2.0

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

  • 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>