This script takes an XML input string, loads it into an XmlDocument, and then converts that XML to a JSON string using the Newtonsoft.Json library.
Converting XML to JSON
usingSystem;usingSystem.Xml;usingNewtonsoft.Json;publicclassFunctionHandler{publicstringHandle(string input) {var xmlDoc =newXmlDocument(); // Set up XML namespace managervar namespaceManager =newXmlNamespaceManager(xmlDoc.NameTable);namespaceManager.AddNamespace("xsi","http://www.w3.org/2001/XMLSchema-instance");namespaceManager.AddNamespace("","http://api.jdplc.com/schemas/mc/pim/feproducts"); // Load the XML string into XmlDocumentxmlDoc.LoadXml(input); // Convert the XML to JSONstring jsonText =JsonConvert.SerializeXmlNode(xmlDoc,Newtonsoft.Json.Formatting.Indented,true);return jsonText; }}
Go
The script below demonstrates the handling of variables, logging, updating response codes, and modifying payloads.
Helper functions demo
JavaScript
The script below demonstrates how to convert a JSON file to XML, using JavaScript.
JSON to XML
PHP
Converting JSON to CSV
Python
The script below demonstrates how to convert a CSV file to JSON, using Python.
CSV to JSON
Rust
The script below demonstrates how helper functions can be used, with the handle() function acting as the main driver.
package function
import (
"encoding/json"
"fmt"
)
type Variables map[string]string
func (v *Variables) UnmarshalJSON(bytes []byte) error {
if string(bytes) == "[]" {
*v = make(Variables)
} else {
d := make(map[string]string)
err := json.Unmarshal(bytes, &d)
if err != nil {
return err
}
*v = d
}
return nil
}
type Request struct {
Payload string `json:"payload"`
Variables Variables `json:"variables,omitempty"`
Flow Flow `json:"flow,omitempty"`
ResponseCode int `json:"response_code,omitempty"`
Message string `json:"message,omitempty"`
Logs []string `json:"logs,omitempty"`
}
func (r *Request) GetVariable(name string) (string, bool) {
if r.Variables == nil {
return "", false
}
value, ok := r.Variables[name]
return value, ok
}
func (r *Request) AddLog(log string) {
r.Logs = append(r.Logs, log)
}
func (r *Request) DeserializePayload() (interface{}, error) {
var payload interface{}
err := json.Unmarshal([]byte(r.Payload), &payload)
if err != nil {
return nil, err
}
return payload, nil
}
type Flow struct {
Variables Variables `json:"variables"`
}
func (f *Flow) GetVariable(name string) (string, bool) {
if f.Variables == nil {
return "", false
}
value, ok := f.Variables[name]
return value, ok
}
// Handle
// handles a serverless request
// example payload:
//
// {
// "payload": "",
// "meta": null,
// "variables": [],
// "flow": {
// "variables": []
// },
// "response_code": 0,
// "message": "",
// "logs": []
// }
func Handle(request []byte) (string, error) {
r := &Request{}
err := json.Unmarshal(request, r)
if err != nil {
return "", fmt.Errorf("failed to deserialize request: %s", err)
}
if r.Variables != nil && len(r.Variables) > 0 {
for k, v := range r.Variables {
r.AddLog(fmt.Sprintf("variable: %s=%s", k, v))
}
} else {
r.AddLog("no variables")
}
if r.Flow.Variables != nil && len(r.Flow.Variables) > 0 {
for k, v := range r.Flow.Variables {
r.AddLog(fmt.Sprintf("flow variable: %s=%s", k, v))
}
} else {
r.AddLog("no flow variables")
}
r.ResponseCode = 12
r.AddLog("updated response code")
r.Variables["key1"] = "value1"
r.Variables["key2"] = "value2"
r.AddLog("added 2 variables (key1, key2)")
var p interface{}
if p, err = r.DeserializePayload(); err != nil {
return "", fmt.Errorf("failed to deserialize payload: %s", err)
}
var ok bool
var m map[string]interface{}
if m, ok = p.(map[string]interface{}); !ok {
r.Payload = "not a json object"
} else {
m["key1"] = "value1"
m["key2"] = "value2"
var result []byte
result, err = json.Marshal(m)
if err != nil {
return "", fmt.Errorf("failed to serialize payload: %s", err)
}
r.Payload = string(result)
}
d, err := json.Marshal(r)
if err != nil {
return "", err
}
return string(d), nil
}
/**
* @param data
* @param {string} data.payload the payload as a string|null
* @param {Object.<string, any>} data.variables any variables as key/value
* @param {Object.<string, any>} data.meta any meta as key/value
*/
module.exports = async function (data) {
var obj = JSON.parse(data.payload)
function jsonToXml(jsonObj, rootName = 'root') {
let xml = '';
const buildXml = (obj, parentName) => {
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const value = obj[key];
if (typeof value === 'object') {
xml += `<${key}>`;
buildXml(value, key);
xml += `</${key}>`;
} else {
xml += `<${key}>${value}</${key}>`;
}
}
}
};
xml += `<?xml version="1.0" encoding="UTF-8"?>`;
xml += `<${rootName}>`;
buildXml(jsonObj, rootName);
xml += `</${rootName}>`;
return xml;
}
const xmlData = jsonToXml(obj, 'data');
const jsonString = JSON.stringify(xmlData);
return {"payload":jsonString};
};
<?php
function handle($data) {
// Decode the JSON string into an array
$dataArray = json_decode($data['payload'], true);
if ($dataArray === null) {
// JSON decoding failed
return 'Failed to decode JSON.';
}
// Create an empty array to store the CSV rows
$csvRows = [];
// Add the CSV headers
if (!empty($dataArray)) {
$headers = array_keys($dataArray[0]);
$csvRows[] = $headers;
}
// Add the CSV rows
foreach ($dataArray as $row) {
$csvRows[] = array_values($row);
}
// Generate the CSV string
$csvString = '';
foreach ($csvRows as $row) {
$csvString .= implode(',', $row) . "\n";
}
// Return the CSV string or error message
return ['payload' => !empty($csvString) ? $csvString : 'Failed to convert JSON to CSV'];
}
# class Request:
# """
# The class representing the request.
# Attributes
# ----------
# payload : str
# the payload as a string or null
# variables : object
# any variables as key/value
# meta : object
# any meta as key/value
# """
def handle(req):
import json, io, csv
data = json.loads(req)
reader = csv.DictReader(io.StringIO(data['payload']), delimiter=';')
json_data = json.dumps(list(reader))
return json.dumps({'payload':json_data})
use bytes::Bytes;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::HashMap;
use crate::GenericError;
use serde::de::{Deserializer, Error as SerdeError, Unexpected};
/// Custom deserializer that converts `[]` into `{}` (empty HashMap)
fn deserialize_variables<'de, D>(deserializer: D) -> Result<HashMap<String, String>, D::Error>
where
D: Deserializer<'de>,
{
match Value::deserialize(deserializer)? {
Value::Object(map) => {
let mut hashmap = HashMap::new();
for (key, value) in map {
if let Value::String(s) = value {
hashmap.insert(key, s);
} else {
return Err(D::Error::custom(format!(
"Expected string values in HashMap, found: {:?}",
value
)));
}
}
Ok(hashmap)
}
Value::Array(arr) if arr.is_empty() => Ok(HashMap::new()), // Convert `[]` to `{}`
other => Err(D::Error::invalid_type(
Unexpected::Other(&format!("{:?}", other)),
&"a map of strings or an empty array",
)),
}
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct RequestBody {
pub payload: Option<String>,
pub meta: Vec<Value>,
#[serde(default, deserialize_with = "deserialize_variables")]
pub variables: HashMap<String, String>,
pub flow: FlowData,
#[serde(default)] // Default value if missing
pub response_code: i32,
#[serde(default)] // Default empty string if missing
pub message: String,
#[serde(default)] // Default empty list if missing
pub logs: Vec<String>,
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct FlowData {
#[serde(default, deserialize_with = "deserialize_variables")]
pub variables: HashMap<String, String>,
}
#[allow(dead_code)]
impl RequestBody {
/// Creates a new `RequestBody` with default values
pub fn new() -> Self {
Self {
payload: None,
meta: Vec::new(),
variables: HashMap::new(),
flow: FlowData {
variables: HashMap::new(),
},
response_code: 0,
message: String::new(),
logs: Vec::new(),
}
}
/// Create a `RequestBody` from `Bytes`
pub fn from_bytes(body_bytes: Bytes) -> Self {
let body_str = String::from_utf8_lossy(&body_bytes);
println!("Received body: {}", body_str); // Debugging output
match serde_json::from_slice(&body_bytes) {
Ok(body) => body,
Err(err) => {
println!("Deserialization error: {}", err); // Print exact deserialization error
let mut default_body = Self::new();
default_body.add_log("Failed to deserialize RequestBody; using default.");
default_body
}
}
}
/// Add a log entry
pub fn add_log(&mut self, message: &str) {
self.logs.push(message.to_string());
}
/// Get the payload as a `String`
pub fn get_payload(&self) -> Option<&String> {
self.payload.as_ref()
}
/// Set a new payload
pub fn set_payload(&mut self, payload: &str) {
self.payload = Some(payload.to_string());
self.add_log(&format!("Payload set to: {}", payload));
}
/// Deserializes the payload into a generic struct if the payload is present and valid JSON
pub fn deserialize_payload<T: for<'de> serde::Deserialize<'de>>(&self) -> Option<T> {
match &self.payload {
Some(payload) if !payload.trim().is_empty() => {
match serde_json::from_str::<T>(payload) {
Ok(deserialized) => Some(deserialized),
Err(err) => {
eprintln!("Failed to deserialize payload: {}", err);
None
}
}
}
_ => {
// Log explicitly that the payload was empty or null
println!("Skipping deserialization: payload is null or empty.");
None
}
}
}
/// Serialize and update the payload from a given struct
pub fn update_payload<T: serde::Serialize>(&mut self, new_payload: &T) {
match serde_json::to_string(new_payload) {
Ok(serialized) => {
self.payload = Some(serialized);
self.add_log("Payload updated successfully.");
}
Err(err) => {
eprintln!("Failed to serialize new payload: {}", err);
self.add_log("Failed to update payload.");
}
}
}
/// Iterate over variables
pub fn variables_iter(&self) -> impl Iterator<Item = (&String, &String)> {
self.variables.iter()
}
/// Add a variable
pub fn add_variable(&mut self, key: &str, value: &str) {
self.variables.insert(key.to_string(), value.to_string());
self.add_log(&format!("Variable added: {} = {}", key, value));
}
/// Get a variable by key
pub fn get_variable(&self, key: &str) -> Option<&String> {
self.variables.get(key)
}
/// Add a flow variable
pub fn add_flow_variable(&mut self, key: &str, value: &str) {
self.flow.variables.insert(key.to_string(), value.to_string());
self.add_log(&format!("Flow variable added: {} = {}", key, value));
}
/// Get a flow variable by key
pub fn get_flow_variable(&self, key: &str) -> Option<&String> {
self.flow.variables.get(key)
}
/// Clear all logs
pub fn clear_logs(&mut self) {
self.logs.clear();
self.add_log("Logs cleared.");
}
/// Reset all variables
pub fn reset_variables(&mut self) {
self.variables.clear();
self.add_log("All variables cleared.");
}
}
#[derive(Deserialize, Serialize, Debug)]
struct CustomPayload {
test: bool,
name: Option<String>,
}
#[allow(unused_mut)]
pub fn handle(body_bytes: Bytes) -> Result<Bytes, GenericError> {
// Deserialize bytes into the `RequestBody` struct
let mut body = RequestBody::from_bytes(body_bytes);
// Check if payload exists and is non-empty before deserializing
if let Some(payload) = &body.payload {
if !payload.trim().is_empty() {
// Attempt to deserialize the payload into `CustomPayload`
if let Some(mut custom_payload) = body.deserialize_payload::<CustomPayload>() {
body.add_log(&format!("Deserialized payload: {:?}", custom_payload));
// Modify the payload
custom_payload.test = !custom_payload.test;
custom_payload.name = Some("Updated Name".to_string());
// Serialize the updated payload back to JSON
body.update_payload(&custom_payload);
} else {
body.add_log("Failed to deserialize payload.");
}
} else {
body.add_log("Payload is empty, skipping deserialization.");
}
} else {
body.add_log("Payload is null, skipping deserialization.");
}
// Add and retrieve variables
body.add_variable("Key1", "Value1");
body.add_variable("Key2", "Value2");
// Collect variables into a temporary Vec to avoid borrowing conflicts
let variables: Vec<(String, String)> = body
.variables_iter()
.map(|(k, v)| (k.clone(), v.clone()))
.collect();
for (key, value) in variables {
body.add_log(&format!("Iterated variable: {} = {}", key, value));
}
// Serialize the updated body back to JSON and return
let response_body = serde_json::to_vec(&body).unwrap();
Ok(Bytes::from(response_body))
}