Reputation: 2493
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>
Upvotes: 0
Views: 397
Reputation: 117043
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>
Upvotes: 1