Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

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,377
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