Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 4.0

...

XML

...

JSON

...

Data

...

Format

...

(camel-xmljson)

...

Available

...

as

...

of

...

Camel

...

2.10

...

Camel

...

already

...

supports

...

a

...

number

...

of

...

data

...

formats

...

to

...

perform

...

XML

...

and

...

JSON-related

...

conversions,

...

but

...

all

...

of

...

them

...

require

...

a

...

POJO

...

either

...

as

...

an

...

input

...

(for

...

marshalling)

...

or

...

produce

...

a

...

POJO

...

as

...

output

...

(for

...

unmarshalling).

...

This

...

data

...

format

...

provides

...

the

...

capability

...

to

...

convert

...

from

...

XML

...

to

...

JSON

...

and

...

viceversa

...

directly,

...

without

...

stepping

...

through

...

intermediate

...

POJOs.

...

This

...

data

...

format

...

leverages

...

the

...

Json-lib

...

library

...

to

...

achieve

...

direct

...

conversion.

...

In

...

this

...

context,

...

XML

...

is

...

considered

...

the

...

high-level

...

format,

...

while

...

JSON

...

is

...

the

...

low-level

...

format.

...

Hence,

...

the

...

marshal/unmarshal

...

semantics

...

are

...

assigned

...

as

...

follows:

...

  • marshalling

...

  • =>

...

  • converting

...

  • from

...

  • XML

...

  • to

...

  • JSON

...

  • unmarshalling

...

  • =>

...

  • converting

...

  • from

...

  • JSON

...

  • to

...

  • XML.

...

Options

This data format supports the following options. You can set them via all DSLs. The defaults marked with (*) are determined by json-lib,

...

rather

...

than

...

the

...

code

...

of

...

the

...

data

...

format

...

itself.

...

They

...

are

...

reflected

...

here

...

for

...

convenience

...

so

...

that

...

you

...

don't

...

have

...

to

...

dot

...

back

...

and

...

forth

...

with

...

the

...

json-lib

...

docs.

Wiki Markup

{div:class=confluenceTableSmall}
|| Name || Type || Default || Description ||
| {{encoding}} | {{String}} | UTF-8 \(*) | *Used when* {color:#008000}{*}unmarshalling{*}{color} *(JSON to XML conversion).* Sets the encoding for the call to [{{XMLSerializer.write()}}|http://json-lib.sourceforge.net/apidocs/net/sf/json/xml/XMLSerializer.html#write(net.sf.json.JSON, java.lang.String)] method, hence it is only used when producing XML. \\
When producing JSON, the encoding is determined by the input String being processed. If the conversion is performed on an InputStream, json-lib uses the platform's default encoding (e.g. determined by the {{file.encoding}} system property). |
| {{elementName}} | {{String}} | 'e' \(*) | *Used when* {color:#008000}{*}unmarshalling{*}{color}* (JSON to XML conversion).* Specifies the name of the XML elements representing each array element. See [json-lib doc|http://json-lib.sourceforge.net/snippets.html#JSONObject_to_XML_change_node_names]. |
| {{arrayName}} | {{String}} | 'a' \(*) | *Used when* {color:#008000}{*}unmarshalling{*}{color}* (JSON to XML conversion).* Specifies the name of the top-level XML element. \\
For example, when converting&nbsp;{{\[1, 2, 3\]}}, it will be output by default as {{<a><e>1</e><e>2</e><e>3</e></a>}}. By setting this option or rootName, you can alter the name of element 'a'. |
| {{rootName}} | {{String}} | none \(*) | *Used when* {color:#008000}{*}unmarshalling{*}{color}*&nbsp;(JSON to XML conversion).* When converting any JSON construct (object, array, null) to XML (unmarshalling), it specifies the name of the top-level element. \\
If not set, json-lib will use {{arrayName}} or&nbsp;{{objectName}} (default value: 'o', at the current time it is not configurable in this data format). If set to 'root', the JSON string \{ 'x': 'value1', 'y' : 'value2' \} would turn into {{<root><x>value1</x><y>value2</y></root>}}, otherwise the 'root' element would be named 'o'. |
| {{namespaceLenient}} | {{Boolean}} | false \(*) | *Used when* {color:#008000}{*}unmarshalling{*}{color}*&nbsp;(JSON to XML conversion).* According to the json-lib docs: "Flag to be tolerant to incomplete namespace prefixes." In most cases, json-lib automatically changes this flag at runtime to match the processing. |
| {{namespaceMappings}} | {{List<NamespacesPerElementMapping>}} | none | *Used when* {color:#008000}{*}unmarshalling{*}{color}*&nbsp;(JSON to XML conversion).* Binds namespace prefixes and URIs to specific JSON elements.&nbsp;{{NamespacesPerElementMapping}} is a wrapper around an element name + a Map of prefixes against URIs. \\ |
| {{expandableProperties}} | {{List<String>}} | none | *Used when* {color:#008000}{*}unmarshalling{*}{color}*&nbsp;(JSON to XML conversion).* With expandable properties, JSON array elements are converted to XML as a sequence of repetitive XML elements with the local name equal to the JSON key, for example: \{ number: 1,2,3 \}, normally converted to: {{<number><e>1</e><e>2</e><e>3</e></number>}} (where e can be modified by setting elementName), would instead translate to {{<number>1</number><number>2</number><number>3</number>}}, if "number" is set as an expandable property |
| {{typeHints}} | {{TypeHintsEnum}} | YES | *Used when* {color:#008000}{*}unmarshalling{*}{color}*&nbsp;(JSON to XML conversion).* Adds type hints to the resulting XML to aid conversion back to JSON.&nbsp;See documentation [here|http://json-lib.sourceforge.net/apidocs/net/sf/json/xml/XMLSerializer.html] for an explanation. {{TypeHintsEnum}} comprises the following values, which lead to different combinations of the underlying XMLSerializer's {{typeHintsEnabled}} and {{typeHintsCompatibility}} flags: \\
* {{TypeHintsEnum.NO}} => {{typeHintsEnabled}}&nbsp;= false
* {{TypeHintsEnum.YES}} =>&nbsp;&nbsp;{{typeHintsEnabled}} = true,&nbsp;&nbsp;{{typeHintsCompatibility}} = true
* {{TypeHintsEnum.WITH_PREFIX}} =>&nbsp;&nbsp;{{typeHintsEnabled}} = true,&nbsp;&nbsp;{{typeHintsCompatibility}} = false |
| {{forceTopLevelObject}} | {{Boolean}} | false \(*) | *Used when* {color:#333399}{*}marshalling{*}{color} *(XML to JSON conversion).* Determines whether the resulting JSON will start off with a top-most element whose name matches the XML root element. If disabled, XML string {{<a><x>1</x><y>2</y></a>}} turns into&nbsp;\{ 'x: '1', 'y': '2' \}. Otherwise, it turns into&nbsp;\{ 'a': \{&nbsp;'x: '1', 'y': '2' \}\}. |
| {{skipWhitespace}} | {{Boolean}} | false \(*) | *Used when* {color:#333399}{*}marshalling{*}{color}*&nbsp;(XML to JSON conversion).* Determines whether white spaces between XML elements will be regarded as text values or disregarded. |
| {{trimSpaces}} | {{Boolean}} | false&nbsp;\(*) | *Used when* {color:#333399}{*}marshalling{*}{color}*&nbsp;(XML to JSON conversion).* Determines whether leading and trailing white spaces will be omitted from String values. |
| {{skipNamespaces}} | {{Boolean}} | false&nbsp;\(*) | *Used when* {color:#333399}{*}marshalling{*}{color}*&nbsp;(XML to JSON conversion).* Signals whether namespaces should be ignored. By default they will be added to the JSON output using @xmlns elements. |
| {{removeNamespacePrefixes}} | {{Boolean}} | false&nbsp;\(*) | *Used when* {color:#333399}{*}marshalling{*}{color}*&nbsp;(XML to JSON conversion).* Removes the namespace prefixes from XML qualified elements, so that the resulting JSON string does not contain them. |
{div}

h3. 

Basic

...

Usage

...

with

...

Java

...

DSL

...

Explicitly

...

instantiating

...

the

...

data

...

format

...

Just

...

instantiate

...

the

...

XmlJsonDataFormat

...

from

...

package

...

org.apache.camel.dataformat.xmljson.

...

Make

...

sure

...

you

...

have

...

installed

...

the

...

camel-xmljson

...

feature

...

(if

...

running

...

on

...

OSGi)

...

or

...

that

...

you've

...

included

...

camel-xmljson-

...

{version

...

}.jar

...

and

...

its

...

transitive

...

dependencies

...

in

...

your

...

classpath.

...

Example

...

initialization

...

with

...

a

...

default

...

configuration:

Code Block
langjava


{code: lang=java}
XmlJsonDataFormat xmlJsonFormat = new XmlJsonDataFormat();
{code}

To

...

tune

...

the

...

behaviour

...

of

...

the

...

data

...

format

...

as

...

per

...

the

...

options

...

above,

...

use

...

the

...

appropriate

...

setters:

Code Block
langjava


{code: lang=java}
XmlJsonDataFormat xmlJsonFormat = new XmlJsonDataFormat();
xmlJsonFormat.setEncoding("UTF-8");
xmlJsonFormat.setForceTopLevelObject(true);
xmlJsonFormat.setTrimSpaces(true);
xmlJsonFormat.setRootName("newRoot");
xmlJsonFormat.setSkipNamespaces(true);
xmlJsonFormat.setRemoveNamespacePrefixes(true);
xmlJsonFormat.setExpandableProperties(Arrays.asList("d", "e"));
{code}

Once

...

you've

...

instantiated

...

the

...

data

...

format,

...

the

...

next

...

step

...

is

...

to

...

actually

...

use

...

the

...

it

...

from

...

within

...

the

...

marshal()

...

and

...

unmarshal()

...

DSL

...

elements:

Code Block
langjava


{code: lang=java}
// from XML to JSON
from("direct:marshal").marshal(xmlJsonFormat).to("mock:json");
// from JSON to XML
from("direct:unmarshal").unmarshal(xmlJsonFormat).to("mock:xml");
{code}

h4. Defining the data format 

Defining the data format in-line

...

Alternatively,

...

you

...

can

...

define

...

the

...

data

...

format

...

inline

...

by

...

using

...

the

...

xmljson()

...

DSL

...

element.

Code Block
langjava


{code: lang=java}
// from XML to JSON - inline dataformat
from("direct:marshalInline").marshal().xmljson().to("mock:jsonInline");
// from JSON to XML - inline dataformat
from("direct:unmarshalInline").unmarshal().xmljson().to("mock:xmlInline");
{code}

If

...

you

...

wish,

...

you

...

can

...

even

...

pass

...

in

...

a

...

Map<String,

...

String>

...

to

...

the

...

inline

...

methods

...

to

...

provide

...

custom

...

options:

Code Block
langjava


{code: lang=java}
Map<String, String> xmlJsonOptions = new HashMap<String, String>();
xmlJsonOptions.put(org.apache.camel.model.dataformat.XmlJsonDataFormat.ENCODING, "UTF-8");
xmlJsonOptions.put(org.apache.camel.model.dataformat.XmlJsonDataFormat.ROOT_NAME, "newRoot");
xmlJsonOptions.put(org.apache.camel.model.dataformat.XmlJsonDataFormat.SKIP_NAMESPACES, "true");
xmlJsonOptions.put(org.apache.camel.model.dataformat.XmlJsonDataFormat.REMOVE_NAMESPACE_PREFIXES, "true");
xmlJsonOptions.put(org.apache.camel.model.dataformat.XmlJsonDataFormat.EXPANDABLE_PROPERTIES, "d e");

// from XML to JSON - inline dataformat w/ options
from("direct:marshalInlineOptions").marshal().xmljson(xmlJsonOptions).to("mock:jsonInlineOptions");
// form JSON to XML - inline dataformat w/ options
from("direct:unmarshalInlineOptions").unmarshal().xmljson(xmlJsonOptions).to("mock:xmlInlineOptions");

Basic usage with Spring or Blueprint DSL

Within the <dataFormats> block, simply configure an xmljson element with unique IDs:

Code Block
langxml
{code}

h3. Basic usage with Spring or Blueprint DSL

Within the {{<dataFormats>}} block, simply configure an {{xmljson}} element with unique IDs:

{code: lang=xml}
<dataFormats>
    <xmljson id="xmljson"/>
    <xmljson id="xmljsonWithOptions" forceTopLevelObject="true" trimSpaces="true" rootName="newRoot" skipNamespaces="true" 
             removeNamespacePrefixes="true" expandableProperties="d e"/>
</dataFormats>
{code}

Then

...

you

...

simply

...

refer

...

to

...

the

...

data

...

format

...

object

...

within

...

your

...

<marshal

...

/>

...

and

...

{<unmarshal

...

/>}}

...

DSLs:

Code Block
langxml


{code: lang=xml}
<route>
    <from uri="direct:marshal"/>
    <marshal ref="xmljson"/>
    <to uri="mock:json" />
</route>

<route>
    <from uri="direct:unmarshalWithOptions"/>
    <unmarshal ref="xmljsonWithOptions"/>
    <to uri="mock:xmlWithOptions"/>
</route>
{code}

Enabling

...

XML

...

DSL

...

autocompletion

...

for

...

this

...

component

...

is

...

easy:

...

just

...

refer

...

to

...

the

...

appropriate

...

Schema

...

locations

...

,

...

depending

...

on

...

whether

...

you're

...

using

...

Spring

...

or

...

Blueprint

...

DSL.

...

Remember

...

that

...

this

...

data

...

format

...

is

...

available

...

from

...

Camel

...

2.10

...

onwards,

...

so

...

only

...

schemas

...

from

...

that

...

version

...

onwards

...

will

...

include

...

these

...

new

...

XML

...

elements

...

and

...

attributes.

...

The

...

syntax

...

with

...

Blueprint

...

is

...

identical

...

to

...

that

...

of

...

the

...

Spring

...

DSL.

...

Just

...

ensure

...

the

...

correct

...

namespaces

...

and

...

schemaLocations

...

are

...

in

...

use.

...

Namespace

...

mappings

...

XML

...

has

...

namespaces

...

to

...

fully

...

qualify

...

elements

...

and

...

attributes;

...

JSON

...

doesn't.

...

You

...

need

...

to

...

take

...

this

...

into

...

account

...

when

...

performing

...

XML-JSON

...

conversions.

...

To

...

bridge

...

the

...

gap,

...

Json

...

-lib

...

has

...

an

...

option

...

to

...

bind

...

namespace

...

declarations

...

in

...

the

...

form

...

of

...

prefixes

...

and

...

namespace

...

URIs

...

to

...

XML

...

output

...

elements

...

while

...

unmarshalling

...

(i.e.

...

converting

...

from

...

JSON

...

to

...

XML).

...

For

...

example,

...

provided

...

the

...

following

...

JSON

...

string:

{
Code Block
}
{ 'pref1:a': 'value1', 'pref2:b': 'value2 }
{code}
 
you can ask 

you can ask Json-lib

...

to

...

output

...

namespace

...

declarations

...

on

...

elements

...

"pref1:a"

...

and

...

"pref2:b"

...

to

...

bind

...

the

...

prefixes

...

"pref1"

...

and

...

"pref2"

...

to

...

specific

...

namespace

...

URIs.

...

To

...

use

...

this

...

feature,

...

simply

...

create

...

XmlJsonDataFormat.NamespacesPerElementMapping

...

objects

...

and

...

add

...

them

...

to

...

the

...

namespaceMappings

...

option

...

(which

...

is

...

a

...

List

...

).

...

The

...

XmlJsonDataFormat.NamespacesPerElementMapping

...

holds

...

an

...

element

...

name

...

and

...

a

...

Map

...

of

...

[prefix

...

=>

...

namespace

...

URI

...

].

...

To

...

facilitate

...

mapping

...

multiple

...

prefixes

...

and

...

namespace

...

URIs,

...

the

...

NamespacesPerElementMapping(String

...

element,

...

String

...

pipeSeparatedMappings)

...

constructor

...

takes

...

a

...

String-based

...

pipe-separated

...

sequence

...

of

...

[prefix,

...

namespaceURI

...

]

...

pairs

...

in

...

the

...

following

...

way:

...

|ns2

...

|http://camel.apache.org/personalData

...

|ns3

...

|http://camel.apache.org/personalData2

...

|

...

.

...

In

...

order

...

to

...

define

...

a

...

default

...

namespace,

...

just

...

leave

...

the

...

corresponding

...

key

...

field

...

empty:

...

|ns1

...

|http://camel.apache.org/test1

...

|

...

|http://camel.apache.org/default

...

|

...

.

...

Binding

...

namespace

...

declarations

...

to

...

an

...

element

...

name

...

=

...

empty

...

string

...

will

...

attach

...

those

...

namespaces

...

to

...

the

...

root

...

element.

...

The

...

full

...

code

...

would

...

look

...

like that:

Code Block
langjava
 that:

{code: lang=java}
XmlJsonDataFormat namespacesFormat = new XmlJsonDataFormat();
List<XmlJsonDataFormat.NamespacesPerElementMapping> namespaces = new ArrayList<XmlJsonDataFormat.NamespacesPerElementMapping>();
namespaces.add(new XmlJsonDataFormat.
                       NamespacesPerElementMapping("", "|ns1|http://camel.apache.org/test1||http://camel.apache.org/default|"));
namespaces.add(new XmlJsonDataFormat.
                       NamespacesPerElementMapping("surname", "|ns2|http://camel.apache.org/personalData|" + 
                           "ns3|http://camel.apache.org/personalData2|"));
namespacesFormat.setNamespaceMappings(namespaces);
namespacesFormat.setRootElement("person");
{code}

And

...

you

...

can

...

achieve

...

the

...

same

...

in

...

Spring

...

DSL.

Example

Using the namespace bindings in the Java snippet above on the following JSON string:

Code Block
langjavascript


h4. Example

Using the namespace bindings in the Java snippet above on the following JSON string:

{code: lang=javascript}
{ "name": "Raul", "surname": "Kripalani", "f": true, "g": null}
{code}

Would

...

yield

...

the

...

following XML:

Code Block
langxml
 XML:

{code: lang=xml}
<person xmlns="http://camel.apache.org/default" xmlns:ns1="http://camel.apache.org/test1">
    <f>true</f>
    <g null="true"/>
    <name>Raul</name>
    <surname xmlns:ns2="http://camel.apache.org/personalData" xmlns:ns3="http://camel.apache.org/personalData2">Kripalani</surname>
</person>
{code}

Remember

...

that

...

the

...

JSON

...

spec

...

defines

...

a

...

JSON

...

object

...

as

...

follows:

...

An object is an unordered set of name/value

...

pairs.

...

[...

...

].

...

That's

...

why

...

the

...

elements

...

are

...

in

...

a

...

different

...

order

...

in

...

the

...

output

...

XML.

Dependencies

To use the XmlJson dataformat in your camel routes you need to add the following dependency to your pom.

Code Block
xml
xml


h3. Dependencies

To use the [XmlJson] dataformat in your camel routes you need to add the following dependency to your pom.

{code:xml}
<dependency>
  <groupId>org.apache.camel</groupId>
  <artifactId>camel-xmljson</artifactId>
  <version>x.x.x</version>
  <!-- Use the same version as camel-core, but remember that this component is only available from 2.10 onwards -->
</dependency>
{code}


h3. See Also

* [Data Format]
* [json-lib|http://json-lib.sourceforge.net/]

See Also