unable to append namespace to object root element using jsontoxml policy

Not applicable

unable to append namespace to object root element using jsontoxml policy

My requirement is like below.

I am going to get input request with JSON format like below

{

"orderNumber":"1111",

"customerId":"1234",

"phoneNumber":"1234-4456-2983"

}

where at Apigee side I need convert this request into XML format like below

<?xml version="1.0"?>

<dupOrderCheck xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<dupOrderCheckRow>

<ordNbr>1111</ordNbr>

<custNbr>1234</custNbr>

</dupOrderCheckRow>

</dupOrderCheck>

To form the request like above, I am using JSONTOXML format. But i am getting the format as below after applying the policy.

<?xml version="1.0" encoding="UTF-8"?>

<dupOrderCheckRow>

<orderNumber>1111</orderNumber>

<customerId>1234</customerId>

</dupOrderCheckRow>

Please help to get the proper format.

Thanks

Sai

Solved Solved
0 4 1,242
1 ACCEPTED SOLUTION

Hello Sai

Well a simple JSON-to-XML policy won't satisfy, because you want to change the structure and the names of the properties. You want to:

  • change the name of orderNumber to ordNbr
  • change the name of customerId to custNbr
  • remove the phoneNumber field
  • add two levels of parent element, dupOrderCheckRow and dupOrderCheck
  • and then finally, transform the JSON to XML

You cannot do all of that in a single JSON-to-XML step. For that you need two steps. You have a couple options.

  • a JSON -to-XML step, followed by an XSL step to modify the structure, OR
  • a JavaScript step to modify the structure, followed by a JSON-to-XML step.

I have produced an example of the latter. The JavaScript looks like this:

 var c = context.getVariable('request.content');
 var json = JSON.parse(c);
 var newObject = { 
    dupOrderCheck : {
        "#namespaces": {
           "xsi": "http://www.w3.org/2001/XMLSchema-instance"
        },
        dupOrderCheckRow : {
            ordNbr : json.orderNumber,
            custNbr : json.customerId
        }
    }
 };
 context.setVariable('request.content', JSON.stringify(newObject));

And the JSON-to-XML step is like this:

<JSONToXML name="JSON-to-XML-1">
    <Options>
        <NamespaceBlockName>#namespaces</NamespaceBlockName>
        <DefaultNamespaceNodeName>$default</DefaultNamespaceNodeName>
        <NamespaceSeparator>:</NamespaceSeparator>
    </Options>
    <OutputVariable>response</OutputVariable>
    <Source>request</Source>
</JSONToXML>

The results are like this:

$ curl -i https://ORG-ENV.apigee.net/sai-jsontoxml \
  -H content-type:application/json \
  -d '{
  "orderNumber":"1111",
  "customerId":"1234",
  "phoneNumber":"1234-4456-2983"
}
'


HTTP/1.1 200 OK
Date: Tue, 05 Sep 2017 22:57:35 GMT
Content-Length: 190
Connection: keep-alive
Server: Apigee Router


<dupOrderCheck xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <dupOrderCheckRow>
      <ordNbr>1111</ordNbr>
      <custNbr>1234</custNbr>
   </dupOrderCheckRow>
</dupOrderCheck>

Please find a working API proxy attached here.

sai-jsontoxml-rev1-2017-09-05.zip

Also note: the xmlns:xsi namespace attribute is unused, and ought to be unnecessary. If your receiving system "needs" that, it's broken. One might also say that a system that generates XML with unused XML namespaces is broken. (I've generated it because you asked for it) The XML above is equivalent to the following:

<dupOrderCheck>
   <dupOrderCheckRow>
      <ordNbr>1111</ordNbr>
      <custNbr>1234</custNbr>
   </dupOrderCheckRow>
</dupOrderCheck>

View solution in original post

4 REPLIES 4

Hi !

The people who patronize the Apigee community site LOVE to answer questions and help people. But we can't help with questions that are not well-framed and specific.

I understand that you are having trouble appending a namespace to a root element, while using the jsontoxml policy.

Can you explain:

  1. the results you expect to see, or desire
  2. what you tried
  3. the results you observe

With a good, clearly-worded question, using .... yknow... sentences and punctuation and stuff like that, we will have a good shot at being able to help you out.

Not applicable

Hi Dino,

My requirement is like below.

I am going to get input request with JSON format like below

{

"orderNumber":"1111",

"customerId":"1234",

"phoneNumber":"1234-4456-2983"

}

where at Apigee side I need convert this request into XML format like below

<?xml version="1.0"?>

<dupOrderCheck xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<dupOrderCheckRow>

<ordNbr>1111</ordNbr>

<custNbr>1234</custNbr>

</dupOrderCheckRow>

</dupOrderCheck>

To form the request like above, I am using JSONTOXML format. But i am getting the format as below after applying the policy.

<?xml version="1.0" encoding="UTF-8"?>

<dupOrderCheckRow>

<orderNumber>1111</orderNumber>

<customerId>1234</customerId>

</dupOrderCheckRow>

Please help to get the proper format.

Thanks

Sai

Hello Sai

Well a simple JSON-to-XML policy won't satisfy, because you want to change the structure and the names of the properties. You want to:

  • change the name of orderNumber to ordNbr
  • change the name of customerId to custNbr
  • remove the phoneNumber field
  • add two levels of parent element, dupOrderCheckRow and dupOrderCheck
  • and then finally, transform the JSON to XML

You cannot do all of that in a single JSON-to-XML step. For that you need two steps. You have a couple options.

  • a JSON -to-XML step, followed by an XSL step to modify the structure, OR
  • a JavaScript step to modify the structure, followed by a JSON-to-XML step.

I have produced an example of the latter. The JavaScript looks like this:

 var c = context.getVariable('request.content');
 var json = JSON.parse(c);
 var newObject = { 
    dupOrderCheck : {
        "#namespaces": {
           "xsi": "http://www.w3.org/2001/XMLSchema-instance"
        },
        dupOrderCheckRow : {
            ordNbr : json.orderNumber,
            custNbr : json.customerId
        }
    }
 };
 context.setVariable('request.content', JSON.stringify(newObject));

And the JSON-to-XML step is like this:

<JSONToXML name="JSON-to-XML-1">
    <Options>
        <NamespaceBlockName>#namespaces</NamespaceBlockName>
        <DefaultNamespaceNodeName>$default</DefaultNamespaceNodeName>
        <NamespaceSeparator>:</NamespaceSeparator>
    </Options>
    <OutputVariable>response</OutputVariable>
    <Source>request</Source>
</JSONToXML>

The results are like this:

$ curl -i https://ORG-ENV.apigee.net/sai-jsontoxml \
  -H content-type:application/json \
  -d '{
  "orderNumber":"1111",
  "customerId":"1234",
  "phoneNumber":"1234-4456-2983"
}
'


HTTP/1.1 200 OK
Date: Tue, 05 Sep 2017 22:57:35 GMT
Content-Length: 190
Connection: keep-alive
Server: Apigee Router


<dupOrderCheck xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <dupOrderCheckRow>
      <ordNbr>1111</ordNbr>
      <custNbr>1234</custNbr>
   </dupOrderCheckRow>
</dupOrderCheck>

Please find a working API proxy attached here.

sai-jsontoxml-rev1-2017-09-05.zip

Also note: the xmlns:xsi namespace attribute is unused, and ought to be unnecessary. If your receiving system "needs" that, it's broken. One might also say that a system that generates XML with unused XML namespaces is broken. (I've generated it because you asked for it) The XML above is equivalent to the following:

<dupOrderCheck>
   <dupOrderCheckRow>
      <ordNbr>1111</ordNbr>
      <custNbr>1234</custNbr>
   </dupOrderCheckRow>
</dupOrderCheck>

Hi Dino,

Thanks a lot. I already made use of XSL transform policy, and got succeeded. But i came to know like changing the property names to different one by your solution. Thank you very much.

Thanks

Sai