Reputation: 2491
After having flattened parsed JSON data, I would like to add several attributes and namespace prefix, based on previous JSON array key grouping. This question is similar to: Add attributes to matched parsed json-to-xml map prior to flatten data
...with the difference that in this case the attributes are attempted to be added after the flattening and without tunneling. Reason of trying to achieve this is to control adding attributes based on previous JSON file array grouping.
I cannot use the method of processing the JSON directly using "parse-json", because this is just a minimal JSON code example. The real data is larger and comes from user which means some data is unknown (thus cannot be hardcoded).
My code is visible here: https://xsltfiddle.liberty-development.net/gVAkJ3X/1
Below you find extractions of code:
data.json
<data>
{
"ix_hidden": [
{
"CompanyName": "Link Inc",
"OrganisationNumber": "123"
}
],
"other": [
{
"SomethingElse": "Juice"
}
]
}
</data>
XSL:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xbrli="http://www.example.com/1"
xmlns:ix="http://www.example.com/2"
xmlns:tx="http://www.example.com/3"
>
<xsl:output method="xml"/>
<!-- Parse JSON to XML -->
<xsl:template match="data">
<xbrli:xbrl>
<xsl:apply-templates select="json-to-xml(.)/*"/>
</xbrli:xbrl>
</xsl:template>
<!-- Flatten data, exlude high-level key names-->
<xsl:template match="*[@key and not(*)]">
<xsl:element name="{@key}">
<xsl:value-of select="."/>
</xsl:element>
<!-- Add attributes and NS prefix to [ix_hidden] -->
<xsl:for-each select="*[@key = 'ix_hidden']/*">
<xsl:attribute name="attributeOne">1</xsl:attribute>
<xsl:attribute name="attributeTwo">2</xsl:attribute>
<xsl:attribute name="attributeThree">3</xsl:attribute>
<xsl:attribute name="attributeFour">4</xsl:attribute>
<xsl:attribute name="attributeFive">5</xsl:attribute>
</xsl:for-each>
<!-- Add attributes and NS prefix to [other] -->
<xsl:for-each select="*[@key = 'other']/*">
<xsl:attribute name="contextRef">balance0</xsl:attribute>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Result
<?xml version="1.0" encoding="UTF-8"?>
<xbrli:xbrl xmlns:ix="http://www.example.com/2" xmlns:xbrli="http://www.example.com/1">
<CompanyName>Link Inc</CompanyName>
<OrganisationNumber>123</OrganisationNumber>
<SomethingElse>Juice</SomethingElse>
</xbrli:xbrl>
Wanted result
<?xml version="1.0" encoding="UTF-8"?>
<xbrli:xbrl xmlns:ix="http://www.example.com/2" xmlns:xbrli="http://www.example.com/1">
<ix:CompanyName attributeOne="1" attributeTwo="2" attributeThree="3" attributeFour="4" attributeFive="5">Link Inc</ix:CompanyName>
<ix:OrganisationNumber attributeOne="1" attributeTwo="2" attributeThree="3" attributeFour="4" attributeFive="5">123</ix:OrganisationNumber>
<tx:SomethingElse contextRef="balance0">Juice</tx:SomethingElse>
</xbrli:xbrl>
Upvotes: 0
Views: 286
Reputation: 167716
I think the following (https://xsltfiddle.liberty-development.net/gVAkJ3X/2) might help:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xbrli="http://www.example.com/1"
xmlns:ix="http://www.example.com/2"
xmlns:tx="http://www.example.com/3"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
exclude-result-prefixes="fn"
expand-text="yes"
>
<xsl:attribute-set name="s1">
<xsl:attribute name="attributeOne">1</xsl:attribute>
<xsl:attribute name="attributeTwo">2</xsl:attribute>
<xsl:attribute name="attributeThree">3</xsl:attribute>
<xsl:attribute name="attributeFour">4</xsl:attribute>
<xsl:attribute name="attributeFive">5</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="s2">
<xsl:attribute name="contextRef">balance0</xsl:attribute>
</xsl:attribute-set>
<xsl:output method="xml" indent="yes"/>
<!-- Parse JSON to XML -->
<xsl:template match="data">
<xbrli:xbrl>
<xsl:apply-templates select="json-to-xml(.)/*"/>
</xbrli:xbrl>
</xsl:template>
<!-- Flatten data, exlude high-level key names-->
<xsl:template match="*[@key and not(*)]">
<xsl:element name="{@key}">{.}</xsl:element>
</xsl:template>
<!-- Add attributes and NS prefix to [ix_hidden] -->
<xsl:template match="fn:array[@key = 'ix_hidden']//*[@key and not(*)]">
<xsl:element name="ix:{@key}" namespace="http://www.example.com/2" use-attribute-sets="s1">{.}</xsl:element>
</xsl:template>
<!-- Add attributes to [other] -->
<xsl:template match="fn:array[@key = 'other']//*[@key and not(*)]">
<xsl:element name="tx:{@key}" namespace="http://www.example.com/3" use-attribute-sets="s2">{.}</xsl:element>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1