1

I am looking to extract values from an array where each array is connected to a object key name. The problem I encounter is not knowing how to structure the inner "xsl:foreach" toward a map array.

I will later differentiate the elements by adding attributes but I left that out to keep the question and data at minimal level.

JSON:

<data>
{
  "datasheets": {
    "balance": {
      "cash": [4, 2, 3, 1],
      "bank": [5, 8, 7, 9]
    }
  }
}
</data>

XSL:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:transform version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:docroot="http://www.example.org/1"
  xmlns:report="http://www.example.org/2"
  xmlns:cells="http://www.example.org/3"
  expand-text="yes"
>

  <xsl:output method="xml" indent="yes"/>

  <xsl:mode on-no-match="shallow-skip"/>

  <!-- Parse JSON to XML -->

  <xsl:template match="data">
    <docroot>
      <xsl:apply-templates select="json-to-xml(.)/*"/>
    </docroot>
  </xsl:template>

  <!-- Transform balance data -->

  <xsl:template match="*[@key = 'balance']">

    <report:yearly-values>

      <xsl:for-each select="./*">

          <!-- <xsl:for-each select="./*"> -->
            <xsl:element name="cells:{@key}">Placeholder</xsl:element>
          <!-- </xsl:for-each> -->

      </xsl:for-each>

    </report:yearly-values>

  </xsl:template>

</xsl:transform>

Result:

<?xml version="1.0" encoding="UTF-8"?>
<docroot xmlns:cells="http://www.example.org/3"
         xmlns:docroot="http://www.example.org/1"
         xmlns:report="http://www.example.org/2">
   <report:yearly-values>
      <cells:cash>Placeholder</cells:cash>
      <cells:bank>Placeholder</cells:bank>
   </report:yearly-values>
</docroot>

Wanted result:

<?xml version="1.0" encoding="UTF-8"?>
<docroot xmlns:cells="http://www.example.org/3"
         xmlns:docroot="http://www.example.org/1"
         xmlns:report="http://www.example.org/2">
   <report:yearly-values>
      <cells:cash>4</cells:cash>
      <cells:cash>2</cells:cash>
      <cells:cash>3</cells:cash>
      <cells:cash>1</cells:cash>
      <cells:bank>5</cells:bank>
      <cells:bank>8</cells:bank>
      <cells:bank>7</cells:bank>
      <cells:bank>9</cells:bank>
   </report:yearly-values>
</docroot>

2 Answers 2

1

When you first take this debugging step to see what is going on:

  <xsl:template match="*[@key = 'balance']">
    
    <report:yearly-values>
      <xsl:copy-of select="."/>
    </report:yearly-values>
    
  </xsl:template>
  

Would give this xml-fragment:

   <report:yearly-values>
      <map xmlns="http://www.w3.org/2005/xpath-functions" key="balance">
         <array key="cash">
            <number>4</number>
            <number>2</number>
            <number>3</number>
            <number>1</number>
         </array>
         <array key="bank">
            <number>5</number>
            <number>8</number>
            <number>7</number>
            <number>9</number>
         </array>
      </map>
   </report:yearly-values>

Then it is more clear what you need. Take the for-each one level deeper and use the @key of the parent for you element-name, like this:

  <xsl:template match="*[@key = 'balance']">
    <report:yearly-values>
       <xsl:for-each select="*/*"> 
          <xsl:element name="cells:{parent::*/@key}"><xsl:value-of select="text()"/></xsl:element>
       </xsl:for-each> 
    </report:yearly-values>
  </xsl:template>
Sign up to request clarification or add additional context in comments.

Comments

1

You're just iterating over the two arrays but not the content of the arrays. The following will produce the wanted output:

<xsl:for-each select="./*/*">

          <!-- <xsl:for-each select="./*/*"> -->
            <xsl:element name="cells:{parent::*/@key}">
              <xsl:value-of select="."/>
            </xsl:element>
          <!-- </xsl:for-each> -->

</xsl:for-each>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.