diff --git a/activity/json2xml/README.md b/activity/json2xml/README.md
new file mode 100644
index 0000000..2552fc9
--- /dev/null
+++ b/activity/json2xml/README.md
@@ -0,0 +1,57 @@
+# JSON2XML
+
+Activity for converting JSON object into XML.
+
+For additional tuneups and syntax take a look at [MXJ](https://github.com/clbanning/mxj) Go package.
+
+
+## Installation
+
+### Flogo CLI
+
+```bash
+flogo install github.com/project-flogo/contrib/activity/json2xml
+```
+
+## Configuration
+
+### Input
+
+| Name | Type | Description |
+|------------|---------|-------------------------------|
+| json | object | Input object in JSON format |
+| xmlRootTag | string | Optional name of XML root tag |
+
+
+### Output
+
+| Name | Type | Description |
+|------|------|----------------|
+| xml | byte | Raw XML Output |
+
+Example converting raw XML byte array into string.
+```
+string.tostring($activity[JsonToXML].xmlData )
+```
+
+## Usage
+
+```json
+{
+ "id": "JsonToXML",
+ "name": "JsonToXML",
+ "activity": {
+ "ref": "github.com/project-flogo/contrib/activity/json2xml",
+ "input": {
+ "xmlRootTag": "",
+ "json": "{\"hello\":\"world\"}"
+ }
+ }
+}
+```
+
+Output:
+```xml
+
+world
+```
\ No newline at end of file
diff --git a/activity/json2xml/activity.go b/activity/json2xml/activity.go
new file mode 100644
index 0000000..d9de293
--- /dev/null
+++ b/activity/json2xml/activity.go
@@ -0,0 +1,78 @@
+// Package json2xml activity for converting JSON object into XML
+package json2xml
+
+import (
+ "encoding/xml"
+ "fmt"
+ "github.com/clbanning/mxj"
+ "github.com/project-flogo/core/activity"
+ "github.com/project-flogo/core/support/log"
+ "strings"
+)
+
+type Activity struct{}
+
+// init Flogo activity
+func init() {
+ _ = activity.Register(&Activity{})
+}
+
+// Default xmlHeader
+var xmlHeader = []byte(xml.Header)
+
+// Precalculated size of default root tags from MXJ package
+var startDefaultRootTagSize = len(mxj.DefaultRootTag) + 2
+var endDefaultRootTagSize = len(mxj.DefaultRootTag) + 3
+
+var metadata = activity.ToMetadata(&Input{}, &Output{})
+
+// Metadata for the Activity
+func (ac *Activity) Metadata() *activity.Metadata {
+ return metadata
+}
+
+func (ac *Activity) Eval(ctx activity.Context) (bool, error) {
+ ctx.Logger().Debugf("Activity [%s] JSON2XML", ctx.Name())
+
+ input := &Input{}
+ var err = ctx.GetInputObject(input)
+ if err != nil {
+ return false, activity.NewError(fmt.Sprintf("Activity [%s] Can't get input JSON object - %s", ctx.Name(), err.Error()), "JSON2XML-01", nil)
+ }
+
+ var out []byte
+ out, err = convert(input.Json, input.XmlRootTag, ctx.Logger())
+ if err != nil {
+ return false, activity.NewError(fmt.Sprintf("Activity [%s] Error converting JSON object [%T] to XML - %s", ctx.Name(), input.Json, err.Error()), "JSON2XML-02", nil)
+ }
+
+ err = ctx.SetOutputObject(&Output{Xml: out})
+ if err != nil {
+ return false, activity.NewError(fmt.Sprintf("Activity [%s] Can't set output XML object - %s", ctx.Name(), err.Error()), "JSON2XML-03", nil)
+ }
+
+ ctx.Logger().Debugf("Activity [%s] JSON2XML completed", ctx.Name())
+ return true, nil
+}
+
+func convert(json map[string]interface{}, xmlRootTag string, log log.Logger) ([]byte, error) {
+ mxj.XMLEscapeChars(true)
+ var data []byte
+ var err error
+ if len(strings.TrimSpace(xmlRootTag)) == 0 {
+ data, err = mxj.AnyXml(json)
+ if json != nil && err == nil {
+ // remove default root tags added by mxj package
+ data = data[startDefaultRootTagSize : len(data)-endDefaultRootTagSize]
+ }
+ } else {
+ data, err = mxj.AnyXml(json, xmlRootTag)
+ }
+
+ var buf []byte
+ buf = append(buf, xmlHeader...)
+ buf = append(buf, data...)
+
+ log.Debugf("Converted JSON object [%T] to XML object [%T] with size of %d", json, buf, len(buf))
+ return buf, err
+}
diff --git a/activity/json2xml/activity_test.go b/activity/json2xml/activity_test.go
new file mode 100644
index 0000000..3c3d75b
--- /dev/null
+++ b/activity/json2xml/activity_test.go
@@ -0,0 +1,205 @@
+package json2xml
+
+import (
+ "encoding/json"
+ "encoding/xml"
+ "fmt"
+ "github.com/clbanning/mxj"
+ "github.com/project-flogo/core/data/coerce"
+ "math"
+ "testing"
+
+ "github.com/project-flogo/core/activity"
+ "github.com/project-flogo/core/support/test"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestRegister(t *testing.T) {
+
+ ref := activity.GetRef(&Activity{})
+ act := activity.Get(ref)
+
+ assert.NotNil(t, act)
+}
+
+func TestStructure(t *testing.T) {
+
+ type NestedData struct {
+ DataA string `json:"data-a" xml:"data-a"`
+ }
+
+ type Data struct {
+ Name string `json:"name" xml:"name"`
+ Special string `json:"spec_chars" xml:"spec_chars"`
+ List []string `json:"list" xml:"list"`
+ Number int `json:"number" xml:"number"`
+ Decimal float32 `json:"decimal" xml:"decimal"`
+ Utf8String string `json:"utf8" xml:"utf8"`
+ Nested NestedData `json:"nested" xml:"nested"`
+ }
+
+ var rawTestData = &Data{
+ Name: "Test Name",
+ Special: "<>&\"'",
+ List: []string{"one", "two", "three"},
+ Number: 43,
+ Decimal: math.Pi,
+ Utf8String: "नमस्ते दुनिया", // Hello World in Hindi
+ Nested: NestedData{
+ DataA: "nested data value",
+ },
+ }
+
+ ac := &Activity{}
+ tc := test.NewActivityContext(ac.Metadata())
+
+ // given
+ var jsonObject, _ = coerce.ToObject(rawTestData) // json object type for Flogo framework
+ t.Logf("Marshaled JSON: %s", jsonObject)
+
+ acInput := &Input{Json: jsonObject, XmlRootTag: "Data"}
+ tc.SetInputObject(acInput)
+
+ // when
+ done, _ := ac.Eval(tc)
+
+ // then
+ acOutput := &Output{}
+ tc.GetOutputObject(acOutput)
+ t.Logf("Marshaled XML: %s", string(acOutput.Xml))
+
+ var outputData = &Data{}
+ var err = xml.Unmarshal(acOutput.Xml, &outputData)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ assert.True(t, done)
+ assert.Equal(t, rawTestData, outputData)
+}
+
+func TestEvalNoXMLRoot(t *testing.T) {
+ // setup
+ ac := &Activity{}
+ tc := test.NewActivityContext(ac.Metadata())
+
+ // given
+ jsonString := `{"hello": "world"}`
+ var jsonObject map[string]interface{}
+ json.Unmarshal([]byte(jsonString), &jsonObject)
+
+ acInput := &Input{Json: jsonObject, XmlRootTag: ""}
+ tc.SetInputObject(acInput)
+
+ // when
+ done, _ := ac.Eval(tc)
+
+ // then
+ acOutput := &Output{}
+ tc.GetOutputObject(acOutput)
+
+ assert.True(t, done)
+ var expectedResult = []byte("\nworld")
+ assert.Equal(t, expectedResult, acOutput.Xml)
+}
+
+func TestEvalCustomXMLRoot(t *testing.T) {
+ // setup
+ ac := &Activity{}
+ tc := test.NewActivityContext(ac.Metadata())
+
+ // given
+ jsonString := `{"hello": "world"}`
+ var jsonObject map[string]interface{}
+ json.Unmarshal([]byte(jsonString), &jsonObject)
+
+ acInput := &Input{Json: jsonObject, XmlRootTag: "my"}
+ tc.SetInputObject(acInput)
+
+ // when
+ done, _ := ac.Eval(tc)
+
+ // then
+ acOutput := &Output{}
+ tc.GetOutputObject(acOutput)
+
+ assert.True(t, done)
+ assert.Contains(t, string(acOutput.Xml), "my")
+}
+
+func TestJsonContainingXML(t *testing.T) {
+ // setup
+ ac := &Activity{}
+ tc := test.NewActivityContext(ac.Metadata())
+
+ // given
+ jsonString := `{"xml": "world"}`
+ var jsonObject map[string]interface{}
+ json.Unmarshal([]byte(jsonString), &jsonObject)
+
+ acInput := &Input{Json: jsonObject}
+ tc.SetInputObject(acInput)
+
+ // when
+ done, _ := ac.Eval(tc)
+
+ // then
+ expectedResult :=
+ `` +
+ "\n" +
+ `<hello>world</hello>`
+ acOutput := &Output{}
+ tc.GetOutputObject(acOutput)
+
+ assert.True(t, done)
+ assert.Equal(t, expectedResult, string(acOutput.Xml))
+}
+
+func TestEmptyCustomXMLRootTag(t *testing.T) {
+ // setup
+ ac := &Activity{}
+ tc := test.NewActivityContext(ac.Metadata())
+
+ // given
+ acInput := &Input{Json: nil, XmlRootTag: "root"}
+ tc.SetInputObject(acInput)
+
+ // when
+ done, _ := ac.Eval(tc)
+
+ // then
+ expectedResult :=
+ `` +
+ "\n" +
+ ``
+ acOutput := &Output{}
+ tc.GetOutputObject(acOutput)
+
+ assert.True(t, done)
+ assert.Equal(t, expectedResult, string(acOutput.Xml))
+}
+
+func TestEmptyDefaultXMLRootTag(t *testing.T) {
+ // setup
+ ac := &Activity{}
+ tc := test.NewActivityContext(ac.Metadata())
+
+ // given
+ acInput := &Input{Json: nil}
+ tc.SetInputObject(acInput)
+
+ // when
+ done, _ := ac.Eval(tc)
+
+ // then
+ expectedResult :=
+ `` +
+ "\n" +
+ fmt.Sprintf("<%s/>", mxj.DefaultRootTag)
+ acOutput := &Output{}
+ tc.GetOutputObject(acOutput)
+
+ assert.True(t, done)
+ assert.Equal(t, expectedResult, string(acOutput.Xml))
+}
diff --git a/activity/json2xml/descriptor.json b/activity/json2xml/descriptor.json
new file mode 100644
index 0000000..2754e50
--- /dev/null
+++ b/activity/json2xml/descriptor.json
@@ -0,0 +1,27 @@
+{
+ "name": "flogo-json2xml",
+ "type": "flogo:activity",
+ "ref": "github.com/project-flogo/contrib/activity/json2xml",
+ "version": "1.0.0",
+ "title": "JSON2XML Activity",
+ "description": "Converts given JSON into XML",
+ "homepage": "https://github.com/project-flogo/contrib/tree/master/activity/json2xml",
+ "input": [
+ {
+ "name": "json",
+ "type": "object",
+ "required": true
+ },
+ {
+ "name": "xmlRootTag",
+ "type": "string",
+ "required": false
+ }
+ ],
+ "output": [
+ {
+ "name": "xml",
+ "type": "bytes"
+ }
+ ]
+}
diff --git a/activity/json2xml/go.mod b/activity/json2xml/go.mod
new file mode 100644
index 0000000..2ecea76
--- /dev/null
+++ b/activity/json2xml/go.mod
@@ -0,0 +1,9 @@
+module github.com/project-flogo/contrib/activity/json2xml
+
+go 1.16
+
+require (
+ github.com/clbanning/mxj v1.8.4
+ github.com/project-flogo/core v1.6.0
+ github.com/stretchr/testify v1.7.1
+)
diff --git a/activity/json2xml/go.sum b/activity/json2xml/go.sum
new file mode 100644
index 0000000..4d70f68
--- /dev/null
+++ b/activity/json2xml/go.sum
@@ -0,0 +1,69 @@
+github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/araddon/dateparse v0.0.0-20190622164848-0fb0a474d195 h1:c4mLfegoDw6OhSJXTd2jUEQgZUQuJWtocudb97Qn9EM=
+github.com/araddon/dateparse v0.0.0-20190622164848-0fb0a474d195/go.mod h1:SLqhdZcd+dF3TEVL2RMoob5bBP5R1P1qkox+HtCBgGI=
+github.com/clbanning/mxj v1.8.4 h1:HuhwZtbyvyOw+3Z1AowPkU87JkJUSv751ELWaiTpj8I=
+github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/project-flogo/core v1.6.0 h1:+LH226SGU5961xh5H9lp8iUGp5dWPHaMYGu0pTuSLSE=
+github.com/project-flogo/core v1.6.0/go.mod h1:fapTXUhLxDeAHyb6eMkuwnYswO8FpZJAMat055QVdJE=
+github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
+github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
+github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
+go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
+go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
+go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
+go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
+go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
+go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM=
+go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs=
+golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
+honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
diff --git a/activity/json2xml/metadata.go b/activity/json2xml/metadata.go
new file mode 100644
index 0000000..af8a19f
--- /dev/null
+++ b/activity/json2xml/metadata.go
@@ -0,0 +1,47 @@
+package json2xml
+
+import (
+ "github.com/project-flogo/core/data/coerce"
+)
+
+type Input struct {
+ Json map[string]interface{} `md:"json"`
+ XmlRootTag string `md:"xmlRootTag"`
+}
+
+func (i *Input) ToMap() map[string]interface{} {
+ return map[string]interface{}{
+ "json": i.Json,
+ "xmlRootTag": i.XmlRootTag,
+ }
+}
+
+func (i *Input) FromMap(values map[string]interface{}) error {
+ var err error
+ i.Json, err = coerce.ToObject(values["json"])
+ i.XmlRootTag, err = coerce.ToString(values["xmlRootTag"])
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+type Output struct {
+ Xml []byte `md:"xml"`
+}
+
+func (o *Output) ToMap() map[string]interface{} {
+ return map[string]interface{}{
+ "xml": o.Xml,
+ }
+}
+
+func (o *Output) FromMap(values map[string]interface{}) error {
+ var err error
+ o.Xml, err = coerce.ToBytes(values["xml"])
+ if err != nil {
+ return err
+ }
+
+ return nil
+}