skip to Main 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>

2

Answers


  1. 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).

    Login or Signup to reply.
  2. 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.)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search