Conversion of Query Parameters to XML

hi,

we are trying to convert json input parameters to XML

ex

query paramerer?name=abc1&name=abc2&name=abc3

to

<name>abc1</name><name>abc2</name><name>abc3</name>

the number of "name" values is dynamic.

I'm able to retrieve the query parameters of "name" using JavaScript .

But facing difficulty to set the values as XML payload using assign message policy.

Is there a methodology to convert to XML payload in this scenario?

Solved Solved
0 2 3,240
1 ACCEPTED SOLUTION

Hi -

I'm not clear on what you want to do. You are saying "json input parameters" but I don't see any JSON. JSON is defined on json.org ; it is a data format, like XML, that allows you to encode arbitrary data. A simple example of a JSON payload representing an address might be:

{
  "address" : {
    "line1" : "123 Main Street",
    "line2" : "Apartment 345",
    "city" : "Belltown",
    "state" : "MD",
    "country" : "US",
    "postalCode" : 12345
  }
}  

JSON uses curly braces, double quotes, colons, and commas to format the data. In your example, you showed none of that. No curlies, no quotes, no commas. So I don't think you are using JSON.

It seems to me that this example:

query paramerer?name=abc1&name=abc2&name=abc3

...represents a query string. Not the same as JSON.

I'm sorry about being pedantic, but now let's get to your question.

I think what you want to do is transform the above querystring data into an XML format. And you say the number of "name" values is dynamic - sometimes there are 2, sometimes 3 or more.

In general, you cannot produce an XML equivalent with AssignMessage. The reason is because the number of occurrences of "name" is dynamic. If the input querystring always had 2 occurrences, or always had 3 occurrences, then you would be able to use an AssignMessage. But you don't have that situation. You have a dynamic number of occurrences of the 'name' parameter. To handle a dynamic number of occurrences, you need a loop, and AssignMessage does not have an internal loop construct. But there is a way to do what you want!

The best way to do what you want may be to loop through the query parameters with logic in a JavaScript callout. For example, the JS code might be like this:

var xmlOutput = '';
var queryStringPairs = context.getVariable("request.querystring").split("&");
queryStringPairs.forEach(function(nameValuePair) {
  var nameAndValue = nameValuePair.split('=');
  if (nameAndValue.length == 2) { // is it a name=value form?
    if (nameAndValue[0] == 'name') {
      xmlOutput += '  <name>' + nameAndValue[1] + '</name>\n';
    }
  }
});
xmlOutput = '<root>\n' + xmlOutput + '</root>\n';
context.setVariable('equivalent_xml', xmlOutput);

What is happening there?

  • get the inbound query string, and split it by ampersands
  • for each of those query parameters, split THAT on the equals sign
  • only if the name part is 'name', append an element to an XML string
  • wrap the XML string in a root element
  • set a context variable with the resulting XML-formatted string.

And the result can be like this:

$ curl -i 'https://ORG-ENV.apigee.net/sujith-qparams/t1?name=abc1&name=abc2&name=abc3'
HTTP/1.1 200 OK
Date: Mon, 28 Aug 2017 16:59:48 GMT
Content-Type: application/xml
Content-Length: 75
Connection: keep-alive
Server: Apigee Router


<root>
  <name>abc1</name>
  <name>abc2</name>
  <name>abc3</name>
</root>

See the attached proxy. sujith-qparams.zip

View solution in original post

2 REPLIES 2

Hi -

I'm not clear on what you want to do. You are saying "json input parameters" but I don't see any JSON. JSON is defined on json.org ; it is a data format, like XML, that allows you to encode arbitrary data. A simple example of a JSON payload representing an address might be:

{
  "address" : {
    "line1" : "123 Main Street",
    "line2" : "Apartment 345",
    "city" : "Belltown",
    "state" : "MD",
    "country" : "US",
    "postalCode" : 12345
  }
}  

JSON uses curly braces, double quotes, colons, and commas to format the data. In your example, you showed none of that. No curlies, no quotes, no commas. So I don't think you are using JSON.

It seems to me that this example:

query paramerer?name=abc1&name=abc2&name=abc3

...represents a query string. Not the same as JSON.

I'm sorry about being pedantic, but now let's get to your question.

I think what you want to do is transform the above querystring data into an XML format. And you say the number of "name" values is dynamic - sometimes there are 2, sometimes 3 or more.

In general, you cannot produce an XML equivalent with AssignMessage. The reason is because the number of occurrences of "name" is dynamic. If the input querystring always had 2 occurrences, or always had 3 occurrences, then you would be able to use an AssignMessage. But you don't have that situation. You have a dynamic number of occurrences of the 'name' parameter. To handle a dynamic number of occurrences, you need a loop, and AssignMessage does not have an internal loop construct. But there is a way to do what you want!

The best way to do what you want may be to loop through the query parameters with logic in a JavaScript callout. For example, the JS code might be like this:

var xmlOutput = '';
var queryStringPairs = context.getVariable("request.querystring").split("&");
queryStringPairs.forEach(function(nameValuePair) {
  var nameAndValue = nameValuePair.split('=');
  if (nameAndValue.length == 2) { // is it a name=value form?
    if (nameAndValue[0] == 'name') {
      xmlOutput += '  <name>' + nameAndValue[1] + '</name>\n';
    }
  }
});
xmlOutput = '<root>\n' + xmlOutput + '</root>\n';
context.setVariable('equivalent_xml', xmlOutput);

What is happening there?

  • get the inbound query string, and split it by ampersands
  • for each of those query parameters, split THAT on the equals sign
  • only if the name part is 'name', append an element to an XML string
  • wrap the XML string in a root element
  • set a context variable with the resulting XML-formatted string.

And the result can be like this:

$ curl -i 'https://ORG-ENV.apigee.net/sujith-qparams/t1?name=abc1&name=abc2&name=abc3'
HTTP/1.1 200 OK
Date: Mon, 28 Aug 2017 16:59:48 GMT
Content-Type: application/xml
Content-Length: 75
Connection: keep-alive
Server: Apigee Router


<root>
  <name>abc1</name>
  <name>abc2</name>
  <name>abc3</name>
</root>

See the attached proxy. sujith-qparams.zip

Excellent illustration , Dino , tried it out and working fine in our "real life" issue

Thank you.