The way to accomplish the task is to register a path for a menu item with an optional argument. If you pass that optional argument along with the request URL callback function will return JSON data else it will return XML data. In that way callback function will serve both data formats.
Following is a coding example of above mentioned scenario.
<?php //hook_perm implementation function example_perm() { return array( 'access city' ); } //hook_menu implementation function example_menu() { $items = array(); //menu item $items['full_city_list'] = array( 'title' => t('City List JSON' ), 'page callback' => 'full_city_list', 'page arguments' => array( 1 ), 'access arguments' => array( 'access city' ), 'type' => MENU_CALLBACK); return $items; } function full_city_list() { $jsonParam=arg(1);//optional argument $result = db_query("SELECT tid,name FROM term_data WHERE vid=2 order by name ASC"); if(strcmp($jsonParam, "json") == 0){ $response = array(); while ($city_data = db_fetch_object($result)) { $response[$city_data->name]['city_name'] = $city_data->name; $response[$city_data->name]['tid'] = $city_data->tid; } if (!empty($response)) { //encodes city data as json $jsonstrCityList = json_encode($response); echo $jsonstrCityList; } else { return false; } }elseif(strcmp($jsonParam, "") == 0){ //sending city data as xml $dom = new DOMDocument("1.0"); $root_elm = $dom->createElement("markers"); $root = $dom->appendChild($root_elm); while ($city_data = db_fetch_object($result)) { $marker_elm = $dom->createElement("marker"); $marker_node = $root->appendChild($marker_elm); $marker_node->setAttribute("name", $city_data->name); $marker_node->setAttribute("tid", $city_data->tid); } header("Content-type: text/xml"); echo $dom->saveXML(); } } ?>
output for http://example.com/full_city_list/json
{"Agalawatta":{"city_name":"Agalawatta","tid":"156"},"Ahungalla":{"city_name":"Ahungalla","tid":"214"},"Akurana":{"city_name":"Akurana","tid":"164"},"Akuressa":{"city_name":"Akuressa","tid":"162"},"Aluthgama":{"city_name":"Aluthgama","tid":"120"},"Ambalangoda":{"city_name":"Ambalangoda","tid":"125"},"Ampara":{"city_name":"Ampara","tid":"211"},"Anuradhapura":{"city_name":"Anuradhapura","tid":"46"},"Arugambay":{"city_name":"Arugambay","tid":"114"},"Avissawella":{"city_name":"Avissawella","tid":"212"},"Badulla":{"city_name":"Badulla","tid":"108"},"Balangoda":{"city_name":"Balangoda","tid":"149"},"Balapitiya":{"city_name":"Balapitiya","tid":"486"},"Bandarawela":{"city_name":"Bandarawela","tid":"197"}}
output for http://example.com/full_city_list
<markers> <marker name="Agalawatta" tid="156"/> <marker name="Ahungalla" tid="214"/> <marker name="Akurana" tid="164"/> <marker name="Akuressa" tid="162"/> <marker name="Aluthgama" tid="120"/> <marker name="Ambalangoda" tid="125"/> <marker name="Ampara" tid="211"/> <marker name="Anuradhapura" tid="46"/> <marker name="Arugambay" tid="114"/> <marker name="Avissawella" tid="212"/> <marker name="Badulla" tid="108"/> <marker name="Balangoda" tid="149"/> <marker name="Balapitiya" tid="486"/> <marker name="Bandarawela" tid="197"/> </markers>