WEBDOOD.COM

JSON to XML

by webdood on Feb.02, 2015, under Software Development

I had a (somewhat bizarre) request to come up with a scheme for having JSON that gets piped out to XML. Figured I’d capture the results. It works pretty well.

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// ServiceDescriptionGeneratorSupport.js
// ======================================
// NOTE - conversion from XML to JSON done by utility found at http://www.utilities-online.info/xmltojson
///////////////////////////////////////////////////////////////////////////////////////////////////////////
var serviceDescription = {
  _structure : {
    "types" : ["Cache", "Flume", "Hadoop", "Hive", "MessagingSystem", "NoSQLDatabase", "RelationalDatabase", "Script", "Search", "Sqoop", "WebService" ],
    "services" : {
      "Cache": {
        "InstanceTemplate": {
          "Service": {
            "DNSName": "poscache",
            "Description": "Caching system for the pos service",
            "Type": "Cache",
            "Zone": "2",
            "NumOfInstances": "1",
            "Host": {
              "Vendor": "memcached",
              "Version": "1.4.15",
              "Name": "posmemcache",
              "ConfigProperties": {
                "Protocol": "TCP",
                "Port": "11230",
                "MaxConns": "1024",
                "MemorySize": "5G"
              }
            }
          }
        }
      },
      "Flume": {
        "InstanceTemplate": {
          "Service": {
            "DNSName": "datafeedflume",
            "Poolname": "datafeedflume",
            "ServiceName": "datafeedflume",
            "Description": "This is the flume service required for hadoop.",
            "Type": "Flume",
            "Zone": "2",
            "Host": {
              "DependentPackages": {
                "Package": [
                  {
                    "-type": "Java",
                    "-version": "1.6.22",
                    "-location": "https://subversion.palm.com/services/CloudServicesV2/Libraries"
                  },
                  {
                    "-type": "Hadoop",
                    "-version": "2.0.5-alpha"
                  }
                ]
              },
              "Vendor": "Apache",
              "Version": "1.4.0"
            }
          }
        }
      },
      "Hadoop": {
        "InstanceTemplate": {
          "Service": {
            "DNSName": "datafeedhadoop",
            "Poolname": "datafeedhadoop",
            "ServiceName": "datafeedhadoop",
            "PodType": "datawarehouse",
            "Description": "This is the datafeed Hadoop cluster.",
            "Type": "Hadoop",
            "Zone": "2",
            "Host": {
              "Vendor": "Apache",
              "Version": "2.0.5-alpha",
              "DependentPackages": {
                "Package": {
                  "-type": "Java",
                  "-version": "1.6.22",
                  "-location": "https://subversion.palm.com/services/CloudServicesV2/Libraries"
                }
              },
              "Components": {
                "HDFS": {
                  "NameNode": {
                    "DNSName": "datafeedhadooppnn",
                    "InstallRequires": {
                      "Memory": "16G",
                      "DiskSpace": "300G"
                    },
                    "ConfigProperties": { "dfs.namenode.name.dir": "/home/hadoop/dfs/name" }
                  },
                  "SecondaryNameNode": {
                    "DNSName": "datafeedhadoopsnn",
                    "InstallRequires": {
                      "Memory": "16G",
                      "DiskSpace": "300G"
                    },
                    "ConfigProperties": { "dfs.namenode.checkpoint.dir": "/home/hadoop/dfs/checkpoint-data" }
                  },
                  "DataNode": {
                    "NumInstances": "5",
                    "DNSName": "datafeedhadooppnn, datafeedhadoopsnn, datafeedhive, datafeedhadoopdn{1..2}",
                    "InstallRequires": {
                      "Memory": "16G",
                      "DiskSpace": "300G"
                    },
                    "ConfigProperties": { "dfs.datanode.data.dir": "/home/hadoop/dfs/data" }
                  },
                  "ConfigProperties": {
                    "dfs.replication": "3",
                    "hadoop.tmp.dir": "/home/hadoop/dfs/tmp"
                  }
                },
                "MapReduce": {
                  "mapreduce.framework.name": "yarn",
                  "Vendor": "Apache",
                  "Version": "2.0.5-alpha",
                  "ConfigProperties": {
                    "mapred.system.dir": "/home/hadoop/mapred/system",
                    "mapred.local.dir": "/home/hadoop/mapred/local"
                  }
                }
              }
            }
          }
        }
      },
      "Hive" : {
        "InstanceTemplate": {
          "Service": {
            "DNSName": "datafeedhive",
            "Poolname": "datafeedhive",
            "ServiceName": "datafeedhive",
            "Description": "Hive to be deployed for datafeedhadoop cluster",
            "Type": "Hive",
            "Zone": "2",
            "Host": {
              "DependentPackages": {
                "Package": [
                  {
                    "-type": "Java",
                    "-version": "1.6.22",
                    "-location": "https://subversion.palm.com/services/CloudServicesV2/Libraries"
                  },
                  {
                    "-type": "Hadoop",
                    "-version": "2.0.5-alpha"
                  }
                ]
              },
              "Vendor": "Apache",
              "Version": "0.10.0",
              "Uses": {
                "Use": {
                  "-RelationalDatabase": "datafeedhivedb",
                  "-lookup": "jdbc/datafeedhivedb",
                  "-scope": "resource"
                }
              },
              "Schema": {
                "SCLocation": {
                  "CronJob": { "-location": "https://subversion.palm.com/services/CloudServicesV2/Development/DataWarehouse/datafeed" }
                }
              }
            }
          }
        }
      },
      "MessagingSystem" : {
        "InstanceTemplate": {
          "Service": {
            "DNSName": "posactivemq",
            "Description": "This is a JMS server used by account services.",
            "Zone": "2",
            "Type": "MessagingSystem",
            "NumberOfInstances": "1",
            "Host": {
              "Vendor": "Apache ActiveMQ",
              "Version": "5.2.0",
              "Name": "posactivemq",
              "InstallRequires": { "DiskSpace": "33MB" },
              "DependantPackages": {
                "Package": {
                  "-type": "Java",
                  "-version": "1.6.22",
                  "-location": "https://subversion.palm.com/services/CloudServicesV2/Libraries"
                }
              },
              "TransportConnectors": {
                "Connector": [
                  {
                    "protocol": "tcp",
                    "port": "61616"
                  },
                  {
                    "protocol": "ssl",
                    "port": "61617"
                  },
                  {
                    "protocol": "stomp",
                    "port": "61613"
                  },
                  {
                    "protocol": "xmpp",
                    "port": "61222"
                  }
                ]
              }
            }
          }
        }
      },
      "NoSQLDatabase" : {
        "InstanceTemplate": {
          "Service": {
            "ServiceName": "sharedriak",
            "DNSName": "sharedriak",
            "Description": "Shared Riak cluster",
            "Zone": "3",
            "Vendor": "Basho",
            "Type": "NoSQLDatabase",
            "ContainerType": "Riak",
            "Version": "1.4.2",
            "LBConfigurations": {
              "VIPProperties": {
                "Type": "Internal",
                "Protocol": "HTTP",
                "Port": "80",
                "Interface": "Top-Down"
              },
              "NodeProperties": {
                "MinNodes": "3",
                "MaxNodes": "5",
                "Port": "8298"
              },
              "HealthMonitorProperties": {
                "Type": "HTTP",
                "Path": "/ping"
              }
            },
            "Host": [
              {
                "DNSName": "sharedriak001",
                "DependentPackages": {
                  "Package": [
                    {
                      "-type": "Erlang",
                      "-version": "R15",
                      "-location": "https://subversion.palm.com/services/CloudServicesV2/Libraries"
                    },
                    {
                      "-type": "Riak",
                      "-version": "1.4.6",
                      "-location": "https://subversion.palm.com/services/CloudServicesV2/Databases"
                    }
                  ]
                },
                "ConfigProperties": { "SCLocation": "https://subversion.palm.com/services/CloudServicesV2/Configurations/Customized/sharedriak" },
                "InstallRequires": {
                  "DiskSpace": "1T",
                  "Memory": "4G",
                  "MaxOpenFiles": "64000"
                },
                "Uses": {
                  "Use": { "-Nas": "platformnas" }
                }
              },
              {
                "DNSName": "sharedriak002",
                "DependentPackages": {
                  "Package": [
                    {
                      "-type": "Erlang",
                      "-version": "R15",
                      "-location": "https://subversion.palm.com/services/CloudServicesV2/Libraries"
                    },
                    {
                      "-type": "Riak",
                      "-version": "1.4.6",
                      "-location": "https://subversion.palm.com/services/CloudServicesV2/Databases"
                    }
                  ]
                },
                "ConfigProperties": { "SCLocation": "https://subversion.palm.com/services/CloudServicesV2/Configurations/Customized/sharedriak" },
                "InstallRequires": {
                  "DiskSpace": "1T",
                  "Memory": "4G",
                  "MaxOpenFiles": "64000"
                },
                "Uses": {
                  "Use": { "-Nas": "platformnas" }
                }
              },
              {
                "DNSName": "sharedriak003",
                "DependentPackages": {
                  "Package": [
                    {
                      "-type": "Erlang",
                      "-version": "R15",
                      "-location": "https://subversion.palm.com/services/CloudServicesV2/Libraries"
                    },
                    {
                      "-type": "Riak",
                      "-version": "1.4.6",
                      "-location": "https://subversion.palm.com/services/CloudServicesV2/Databases"
                    }
                  ]
                },
                "ConfigProperties": { "SCLocation": "https://subversion.palm.com/services/CloudServicesV2/Configurations/Customized/sharedriak" },
                "InstallRequires": {
                  "DiskSpace": "1T",
                  "Memory": "4G",
                  "MaxOpenFiles": "64000"
                },
                "Uses": {
                  "Use": { "-Nas": "platformnas" }
                }
              }
            ]
          }
        }
      },
      "RelationalDatabase" : {
        "InstanceTemplate": {
          "Service": {
            "DNSName": "posdb",
            "Description": "Database schema to host data for pos services.",
            "Type": "RelationalDatabase",
            "Zone": "2",
            "Host": {
              "Vendor": "mySQL",
              "Version": "5.5.31",
              "InstallRequires": { "TableSpace": "2T" },
              "Schema": {
                "Name": "posdb",
                "ConfigProperties": { "Port": "3306" },
                "SCLocation": { "Base": "http://subversion.palm.com/services/CloudServicesV2/Data/" },
                "AccessControl": {
                  "Account": {
                    "Name": "posuser",
                    "AccessLevel": "DML",
                    "Password": "posuser"
                  }
                }
              }
            }
          },
          "Properties": {
            "Provision": {
              "Property": [
                {
                  "-type": "Credential",
                  "-name": "Username",
                  "-value": "posuser"
                },
                {
                  "-type": "Credential",
                  "-name": "Password",
                  "-value": "posuser"
                }
              ]
            }
          }
        }
      },
      "Script" : {
        "InstanceTemplate": {
          "Service": {
            "DNSName": "roboscheduler",
            "ServiceName": "roboscheduler",
            "PodType": "core",
            "Description": "This service is to set cronjobs on hosts",
            "Type": "Script",
            "Zone": "admin",
            "Host": {
              "Container": {
                "-name": "Script",
                "ConfigProperties": {
                  "ConfigLocation": "https://subversion.palm.com/services/CloudServicesV2/Configurations/Customized/roboscheduler"
                },
                "Application": {
                  "-location": "http://subversion.palm.com/services/CloudServicesV2/roboscripts/roboscheduler/",
                  "ConfigProperties": { "SCLocation": "https://subversion.palm.com/services/CloudServicesV2/Configurations/Customized/roboscheduler" },
                  "ContextRoot" : "",
                  "MasterProject" : "",
                  "AboutPages" : "",
                  "VersionPage" : "",
                  "PostDeployCommand" : "",
                  "Uses": ""
                }
              }
            }
          }
        }
      },
      "Search" : {
        "InstanceTemplate": {
          "Service": {
            "ServiceName": "searches",
            "DNSName": "searches",
            "Description": "This is elastic search for the search service.",
            "Zone": "3",
            "Type": "Search",
            "ContainerType": "elasticSearch",
            "Vendor": "ElasticSearch",
            "Version": "0.19.11-3",
            "LBConfigurations": {
              "VIPProperties": {
                "Type": "Internal",
                "Protocol": "HTTP",
                "Port": "80",
                "Interface": "Top-Down"
              },
              "NodeProperties": {
                "NumNodes": "3",
                "Port": "9400"
              },
              "HealthMonitorProperties": {
                "Type": "HTTP",
                "Path": "/_nodes/_local"
              }
            },
            "Cluster": {
              "ClusterName": "MDR",
              "PathData": "/var/lib/elasticsearch/MDR",
              "PathLogs": "/var/log/elasticsearch",
              "MinMasterNodes": "2",
              "Host": [
                {
                  "DNSName": "search001",
                  "Type": "Both",
                  "DependentPackages": {
                    "Package": {
                      "-type": "Java",
                      "-version": "1.6.22",
                      "-location": "https://subversion.palm.com/services/CloudServicesV2/Libraries"
                    }
                  },
                  "InstallRequires": {
                    "ES_HEAP_SIZE": "2G",
                    "LogsSpace": "5G",
                    "DataSpace": "1G",
                    "MaxOpenFiles": "64K"
                  },
                  "Config": { "Location": "https://subversion.palm.com/services/CloudServicesV2/Configurations/Customized" }
                },
                {
                  "DNSName": "search002",
                  "Type": "Both",
                  "DependentPackages": {
                    "Package": {
                      "-type": "Java",
                      "-version": "1.6.22",
                      "-location": "https://subversion.palm.com/services/CloudServicesV2/Libraries"
                    }
                  },
                  "InstallRequires": {
                    "ES_HEAP_SIZE": "2G",
                    "LogsSpace": "5G",
                    "DataSpace": "1G",
                    "MaxOpenFiles": "64K"
                  },
                  "Config": { "Location": "https://subversion.palm.com/services/CloudServicesV2/Configurations/Customized" }
                },
                {
                  "DNSName": "search003",
                  "Type": "Both",
                  "DependentPackages": {
                    "Package": {
                      "-type": "Java",
                      "-version": "1.6.22",
                      "-location": "https://subversion.palm.com/services/CloudServicesV2/Libraries"
                    }
                  },
                  "InstallRequires": {
                    "ES_HEAP_SIZE": "2G",
                    "LogsSpace": "5G",
                    "DataSpace": "1G",
                    "MaxOpenFiles": "64K"
                  },
                  "Config": { "Location": "https://subversion.palm.com/services/CloudServicesV2/Configurations/Customized" }
                },
                {
                  "DNSName": "xcesnode001",
                  "Type": "Both",
                  "DependentPackages": {
                    "Package": {
                      "-type": "Java",
                      "-version": "1.6.22",
                      "-location": "https://subversion.palm.com/services/CloudServicesV2/Libraries"
                    }
                  },
                  "InstallRequires": {
                    "ES_HEAP_SIZE": "2G",
                    "LogsSpace": "5G",
                    "DataSpace": "1G",
                    "MaxOpenFiles": "64K"
                  },
                  "Config": { "Location": "https://subversion.palm.com/services/CloudServicesV2/Configurations/Customized" }
                }
              ]
            }
          }
        }
      },
      "Sqoop" : {
        "InstanceTemplate": {
          "Service": {
            "DNSName": "datafeedsqoop",
            "Poolname": "datafeedsqoop",
            "ServiceName": "datafeedsqoop",
            "PodType": "datawarehouse",
            "Description": "This is the Sqoop service, which should be installed on same server with hive.",
            "Type": "Sqoop",
            "Zone": "2",
            "Host": {
              "DependentPackages": {
                "Package": [
                  {
                    "-type": "Java",
                    "-version": "1.6.22",
                    "-location": "https://subversion.palm.com/services/CloudServicesV2/Libraries"
                  },
                  {
                    "-type": "Hadoop",
                    "-version": "2.2.0"
                  }
                ]
              },
              "Vendor": "Apache",
              "Version": "2.0.5-alpha"
            }
          }
        }
      },
      "WebService" : {
        "InstanceTemplate": {
          "Service": {
            "DNSName": "pos",
            "Poolname": "pos",
            "PodType": "all",
            "ServiceName": "pos",
            "Description": "This is the proxy of services.",
            "Type": "WebService",
            "Zone": "1",
            "LBConfigurations": {
              "VIPProperties": {
                "Type": "External",
                "Protocol": "HTTPS",
                "Port": "443",
                "Interface": "Top-Down"
              },
              "NodeProperties": {
                "MinNodes": "8",
                "MaxNodes": "128",
                "Port": "9760"
              },
              "HealthMonitorProperties": {
                "Type": "HTTP",
                "Path": "/healthcheck"
              },
              "Certificates": {
                "Cert": {
                  "-type": "LB-SSL",
                  "Properties": {
                    "ClientType": "External",
                    "Wildcard": "false",
                    "Issuer": "Verisign"
                  }
                }
              }
            },
            "Host": {
              "InstallRequires": {
                "Memory": "1024M",
                "DiskSpace": "400M"
              },
              "DependentPackages": {
                "Package": {
                  "-type": "Java",
                  "-version": "1.6.22",
                  "-location": "https://subversion.palm.com/services/CloudServicesV2/Libraries"
                }
              },
              "Container": {
                "-name": "Tomcat",
                "-version": "6.0.43",
                "-location": "https://subversion.palm.com/services/CloudServicesV2/Configurations/Base",
                "ConfigProperties": { "ConfigLocation": "https://subversion.palm.com/services/CloudServicesV2/Configurations/Customized/pos" },
                "Application": {
                  "-location": "https://subversion.palm.com/services/CloudServicesV2/Development/Platform/pos",
                  "ConfigProperties": { "SCLocation": "https://subversion.palm.com/services/CloudServicesV2/Configurations/Customized/pos" },
                  "MasterProject": "pos",
                  "AboutPage": "/about",
                  "VersionPage": "/cnc/version?component=pos",
                  "Uses": {
                    "Use": [
                      {
                        "-RelationalDatabase": "posdb",
                        "-lookup": "jdbc/posdb",
                        "-scope": "resource"
                      },
                      {
                        "-Cache": "poscache",
                        "-lookup": "poscache_servers",
                        "-scope": "context"
                      },
                      {
                        "-MessagingSystem": "posactivemq",
                        "-lookup": "posactivemq_servers",
                        "-scope": "resource"
                      }
                    ]
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  ////////////////////////////////////////////////////////////////////////////////////////////////
  // init
  // ====
  ////////////////////////////////////////////////////////////////////////////////////////////////
  init : function() {
    var serviceTypes = this._structure.types.sort(),
      bigString = '


';
    for (var i=0, iEnd=serviceTypes.length;i' + serviceTypes[i] + '

';
    }
    document.getElementById('serviceTypes').innerHTML = bigString;
    this.generateXML();
  },
  ////////////////////////////////////////////////////////////////////////////////////////////////
  // generateXML
  // ===========
  ////////////////////////////////////////////////////////////////////////////////////////////////
  generateXML : function() {
    var oTypePicker = document.getElementById('serviceTypes'),
      serviceType = oTypePicker.options[oTypePicker.selectedIndex].value,
      bigString = "";
    if (serviceType!=="choose") {
      bigString = this.XMLSupport.jsonToXML(null, this._structure.services[ serviceType ], 0);
    }
    bigString = bigString.replace(/')
            break;
          case (this.utility.isArray(value)) :                        // If we have an array, we have a number of nodes with the same name
            retVal.push(this.arrayToXML(nodeName, value, level));
            break;
          case (this.utility.isObject(value)) :                       // If we have another JSON Object, recurse
            retVal.push(this.jsonToXML(nodeName, value, level));
            break;
          default :                                                   // We have a simple scalar value
            retVal.push(this.scalarToXML(nodeName, value, level));
            break;
        }
      }
      return retVal;
    },
    ////////////////////////////////////////////////////////////////////////////////////////////////
    // jsonToXML(STRING nodeName, OBJECT node, INT level) - takes an arbitrary JSON structure
    // ==================================================   and returns well-formed XML.
    // This is a recursive-friendly function. "level" indicates how many (2X) spaces indentation
    ////////////////////////////////////////////////////////////////////////////////////////////////
    jsonToXML : function(nodeName, node, level) {
      var attributePile  = [],
          elementPile    = [],
          indentation    = new Array(level * 2 + 1).join(this._constants.indentationCharacter);

      for (var key in node) {
        if (node.hasOwnProperty(key)) {
          var value = node[ key ];
          if (key.charAt(0)===this._constants.attributePrefix) {          // If we are dealing with an attribute on a node
            attributePile.push(' ' + key.substring(1) + '="' + value + '"');  // Push the attribute onto a stack
          } else {
            switch(true) {
              case (typeof(value)==="undefined" || value===null) :        // If we have no attributes or content, it is a self-closing, empty XML node
                elementPile.push(indentation + '<' + key + ' />')
                break;
              case (this.utility.isArray(value)) :                        // If we have an array, we have a number of nodes with the same name
                var arrayAsXML = this.arrayToXML(key, value, level + 1);
                for (var i=0,iEnd=arrayAsXML.length;i 1) ? new Array((level-1) * 2 + 1).join(this._constants.indentationCharacter) : "",
          retVal     = elementPile.join("");
      if (!(typeof(nodeName) == "undefined" || nodeName===null)) {
        if (elementPile.length>0) {
          if (retVal.match(/\n/)) {
            retVal = '<' + nodeName + attributes + '>\n' + retVal + closingIndentation + '\n';
          } else {
            retVal = '<' + nodeName + attributes + '>' + retVal + closingIndentation + '\n';
          }
        } else {
          retVal = '<' + nodeName + attributes + ' />\n';
        }
      }
      return retVal;
    },
    ////////////////////////////////////////////////////////////////////////////////////////////////
    // scalarToXML(STRING nodeName, STRING value, INT level) - takes a scalar value and returns well-formed XML.
    // =====================================================
    // This is a recursive-friendly function. "level" indicates how many (2X) spaces indentation
    ////////////////////////////////////////////////////////////////////////////////////////////////
    scalarToXML : function(nodeName, value) {
      var retVal      = '<' + nodeName + '>' + value + '\n';
      return retVal;
    },
    ////////////////////////////////////////////////////////////////////////////////////////////////
    // utility - XMLSupport utility methods go here
    // *******
    ////////////////////////////////////////////////////////////////////////////////////////////////
    utility : {
      isArray : function(anArray) {
        return Object.prototype.toString.apply(anArray) === "[object Array]";
      },
      isObject : function( aThing ) {
        return (typeof aThing==="object");
      }
    }
  }
}

Leave a Reply

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Blogroll

A few highly recommended websites...

  • A List Apart
  • Dive into HTML5
  • Javascript: The Good Parts
  • QuirksMode.org