0

Building a table using parsed JSON file as data input. Each value inside the JSON array should be distributed, meanwhile when running the code both values in the JSON array is injected in the same element xml value.

In the code area where I build the "xsl:element" I can manually swap between following which gives me the array content one at at time, but I don't understand how I would make the code iterate over the array data:

<xsl:value-of select="*[1]"/>
<xsl:value-of select="*[2]"/>

JSON:

<data>
{
  "balance-sheets": {
    "sheet-results": {
      "sales": {"values": [3, 5], "title": "Annual sales summary"},
      "costs": {"values": [7, 9], "title": "Accumulated costs per year"}
    }
  }
}
</data>

XSL:

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

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

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

  <!-- Block all data that has no user defined template -->
  <xsl:mode on-no-match="shallow-skip"/>

  <xsl:attribute-set name="base">
    <xsl:attribute name="name">se:{parent::*/@key}</xsl:attribute>
  </xsl:attribute-set>

  <!-- Parse JSON file content to XML map -->
  <xsl:template match="data">
    <store>
      <xsl:apply-templates select="json-to-xml(.)/*"/>
    </store>
  </xsl:template>

  <xsl:template match="*[@key='sheet-results']">

    <table>

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

          <tr>

          <td>
            <xsl:value-of select="*[2]"/>
          </td>

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

            <td>
              <span>

                <xsl:element
                  name="ix:nonFraction"
                  use-attribute-sets="base"
                  >
                  <xsl:value-of select="*"/>
                </xsl:element>
              </span>
            </td>

          </xsl:for-each>

      </tr>

        </xsl:for-each>

    </table>

  </xsl:template>

</xsl:transform>

Result:

<?xml version="1.0" encoding="UTF-8"?>
<store xmlns:ix="http://www.example.org/1" xmlns:se="http://www.example.org/2">
   <table>
      <tr>
         <td>Annual sales summary</td>
         <td>
            <span>
               <ix:nonFraction name="se:sales">3 5</ix:nonFraction>
            </span>
         </td>
         <td>
            <span>
               <ix:nonFraction name="se:sales"/>
            </span>
         </td>
      </tr>
      <tr>
         <td>Accumulated costs per year</td>
         <td>
            <span>
               <ix:nonFraction name="se:costs">7 9</ix:nonFraction>
            </span>
         </td>
         <td>
            <span>
               <ix:nonFraction name="se:costs"/>
            </span>
         </td>
      </tr>
   </table>
</store>

Wanted result:

<?xml version="1.0" encoding="UTF-8"?>
<store xmlns:ix="http://www.example.org/1" xmlns:se="http://www.example.org/2">
   <table>
      <tr>
         <td>Annual sales summary</td>
         <td>
            <span>
               <ix:nonFraction name="se:sales">3</ix:nonFraction>
            </span>
         </td>
         <td>
            <span>
               <ix:nonFraction name="se:sales">5</ix:nonFraction>
            </span>
         </td>
      </tr>
      <tr>
         <td>Accumulated costs per year</td>
         <td>
            <span>
               <ix:nonFraction name="se:costs">7</ix:nonFraction>
            </span>
         </td>
         <td>
            <span>
               <ix:nonFraction name="se:costs">9</ix:nonFraction>
            </span>
         </td>
      </tr>
   </table>
</store>
0

1 Answer 1

1

Consider the following simplified example:

XSLT 3.0

<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:js="http://www.w3.org/2005/xpath-functions"
exclude-result-prefixes="js">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/">
    <table>
        <xsl:for-each select="json-to-xml(data)/js:map/js:map/js:map/js:map">
            <tr>
                <th>
                    <xsl:value-of select="js:string[@key='title']"/>
                </th>
                <xsl:for-each select="js:array[@key='values']/js:number">
                    <td>
                        <xsl:value-of select="."/>
                    </td>
                </xsl:for-each>
            </tr>
        </xsl:for-each>
    </table>
</xsl:template>

</xsl:stylesheet>

Applied to your input example, this will return:

Result

<?xml version="1.0" encoding="UTF-8"?>
<table>
   <tr>
      <th>Annual sales summary</th>
      <td>3</td>
      <td>5</td>
   </tr>
   <tr>
      <th>Accumulated costs per year</th>
      <td>7</td>
      <td>9</td>
   </tr>
</table>
Sign up to request clarification or add additional context in comments.

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.