Shud
Shud

Reputation: 11

JSON to XML using XSLT with changing the content

I want to convert existing json file to xml file and some values: json file:

    {
    "Code": "111",
    "UnitCode": "XYZ",
    "valueCond": {
        "ir": "#001",
        "nk": "portal"
    },
    "property": "AFB139"
    }

desire xml file:

    <map>
    <Code>111</Code>
    <UnitCode>XYZ</UnitCode>
    <valueCond> 
        <ir>#001_1234</ir>
        <nk>portal:zeo</nk>
    <valueCond>
    <property>AFB139<property>
    </map>

I use function json-to-xml, but in the result I get only values without name of elements...How in the result file I can have xml structure with element and values

    <xsl:template name="xsl:initial-template">
        <xsl:variable name="json-as-xml" select="json-to-xml(unparsed-text($input-json)"/>
        <xsl:apply-templates select="$json-as-xml"/>
    
    </xsl:template>

Upvotes: 0

Views: 62

Answers (2)

Michael Kay
Michael Kay

Reputation: 163595

I don't think I would use json-to-xml for this. I would do it "by hand":

<xsl:template name="xsl:initial-template" expand-text="yes">
  <xsl:variable name="json" select="json-doc(...)"/>
  <map>
    <Code>{$json?Code}</Code>
    <UnitCode>{$json?UnitCode}</UnitCode>
    <valueCond> 
        <ir>{$json?valueCond?ir}</ir>
        <nk>{$json?valueCond?nk}</nk>
    <valueCond>
    <property>{$json?property}<property>
  </map>
</xsl:template>

(Adding any data changes that you need to make at the same time - these aren't clear in your requirements.)

Upvotes: 1

Martin Honnen
Martin Honnen

Reputation: 167716

Well, you need to transform the result of json-to-xml further e.g.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="3.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xpath-default-namespace="http://www.w3.org/2005/xpath-functions"
  exclude-result-prefixes="#all"
  expand-text="yes">
  
  <xsl:output indent="yes"/>

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

  <xsl:template name="xsl:initial-template">
    <xsl:variable name="json-as-xml" select="json-to-xml(unparsed-text($input-json)"/>
    <xsl:apply-templates select="$json-as-xml"/>

  </xsl:template>
  
  <xsl:template match="map[not(@key)]">
    <map>
      <xsl:apply-templates/>
    </map>
  </xsl:template>
  
  <xsl:template match="*[@key]">
    <xsl:element name="{@key}">
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>
  
</xsl:stylesheet>

Result is e.g.

<map>
   <UnitCode>XYZ</UnitCode>
   <property>AFB139</property>
   <valueCond>
      <ir>#001</ir>
      <nk>portal</nk>
   </valueCond>
   <Code>111</Code>
</map>

Add further templates like e.g.

  <xsl:template match="string[@key = 'ir' and . = '#001']">
    <xsl:element name="{@key}">{. || '_1234'}</xsl:element>
  </xsl:template>
  
  <xsl:template match="string[@key = 'nk' and . = 'portal']">
    <xsl:element name="{@key}">{. || ':zeo'}</xsl:element>
  </xsl:template>

to change those values and get e.g.

<map>
   <UnitCode>XYZ</UnitCode>
   <property>AFB139</property>
   <valueCond>
      <ir>#001_1234</ir>
      <nk>portal:zeo</nk>
   </valueCond>
   <Code>111</Code>
</map>

Online fiddle example (JSON is inlined there as string param value).

Upvotes: 1

Related Questions