skip to Main Content

I am new to xslt,
I have a xml containing those elements

<cbl:ShippingAddress>
    <cbl:AddressLine AddressLineNumber="1">
        <cbl:Line>line1</cbl:Line>
    </cbl:AddressLine>
    <cbl:AddressLine AddressLineNumber="2">
        <cbl:Line>line2</cbl:Line>
    </cbl:AddressLine>
</cbl:ShippingAddress>

using this code

<map key="address">
    <array key="lines">
      <xsl:for-each select="/cbl:ShippingAddress/cbl:AddressLine/cbl:Line">
        <map>
          <string key="line">{.}</string>
        </map>
      </xsl:for-each>
    </array>
</map>

I get the output

"lines": [
    {
      "line": "line1"
    },
    {
      "line": "line2"
    }
],

I need my output to be like this, but can’t figure out how

"lines": [
    "line1",
    "line2"
],

if i just change <array key="lines"> to <array>
I get the error message :

xml-to-json: Child elements of must have a key attribute

is there a simple way to achieve this? i’ve browse many example, couldn’t find it

2

Answers


  1. Example

    <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"
      xmlns="http://www.w3.org/2005/xpath-functions"
      xmlns:cbl="http://example.com/cbl"
      expand-text="yes">
    
      <xsl:output method="text"/>
    
      <xsl:template match="/" name="xsl:initial-template">
        <xsl:variable name="json-xml">
          <map>
            <array key="lines">
              <xsl:for-each select="cbl:ShippingAddress/cbl:AddressLine/cbl:Line/string()">
                <string>{.}</string>
              </xsl:for-each>
            </array>       
          </map>
        </xsl:variable>
        <xsl:value-of select="xml-to-json($json-xml, map { 'indent' : true() })"/>
      </xsl:template>
    
    </xsl:stylesheet>
    

    Online fiddle example.

    Login or Signup to reply.
  2. Here’s another way you could look at this:

    XML (corrected to well-formed!)

    <cbl:ShippingAddress xmlns:cbl="http://example.com/cbl">
        <cbl:AddressLine AddressLineNumber="1">
            <cbl:Line>line1</cbl:Line>
        </cbl:AddressLine>
        <cbl:AddressLine AddressLineNumber="2">
            <cbl:Line>line2</cbl:Line>
        </cbl:AddressLine>
    </cbl:ShippingAddress>
    

    XSLT 3.0

    <xsl:stylesheet version="3.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xpath-default-namespace="http://example.com/cbl">
    <xsl:output method="json" indent="yes" encoding="UTF-8"/>
    
    <xsl:template match="/ShippingAddress">
        <xsl:sequence select="map{'lines':array{AddressLine/Line/text()}}" />
    </xsl:template>
    
    </xsl:stylesheet>
    

    Result

    { "lines": [
        "line1",
        "line2"
      ] }
    

    Demo

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search