getbody in XML instead of JSON
@chriskapp I am creating a gateway action for an api that expects XML and returns XML.
For passing the body i need the body in XML. ( can be different XML ) ( using pasethrough ) But i can only get the body in JSON as described. Is there a way to get the original BODY. I have been digging through the src but cant find . Or do need convert the JSON back to XML.
The JSON body is missing the top level btw.
<Messages>
<Message>
<id>1</id>
<title>a title</title>
</Message>
</Messages>
is giving me
{
"Message" : {
"id" : 1
"title": "a title"
}
}
instead of
{
"Messages" : {
"Message" : {
"id" : 1
"title": "a title"
}
}
}
Also if i want to rebuild the XML i have the problem that XML->jSON elements with preceding 0 are seen as integers instead of string.
<Messages>
<Message>
<id>1</id>
<elementwithprecedingzero>00000011121</elementwithprecedingzero>
<title>a title</title>
</Message>
</Messages>
{
"Message" : {
"id" : 1
"elementwithprecedingzero" : 11121
"title": "a title"
}
}
Hi, so Fusio tries to parse your XML structure into an object structure which is similar to JSON because of this Fusio can also validate your XML input if you provide a request schema at a route and in general the complete system works with this structure. The XML parsing process is not perfect, if you like you can take a look at the XML transformer s. https://github.com/apioo/psx-data/blob/master/src/Transformer/XmlArray.php which builds the object structure based on the raw XML input.
for also extracting rootElementname
Following change
public function transform($data)
{
if (!$data instanceof DOMDocument) {
throw new InvalidArgumentException('Data must be an instanceof DOMDocument');
}
$rootelement=$data->documentElement;
$result = new \stdClass();
$result->{$rootelement->nodeName}=$this->recToXml($data->documentElement);
return $result;
}
and to assign String to numbers starting with 0
protected function parseValue($value)
{
if (is_numeric($value) && ( strlen($value)>1 && strncmp($value, "0", 1) != 0) ) {
return strpos($value, '.') !== false ? (float) $value : (int) $value;
} elseif ($value === 'true' || $value === '1') {
return true;
} elseif ($value === 'false' || $value === '0') {
return false;
} else {
return $value;
}
}
In PHPSandbox Action
function is_assoc_array($array){
if(is_array($array) !== true){
return false;
}else{
$check = json_decode(json_encode($array));
if(is_object($check) === true){
return true;
}else{
return false;
}
}
}
/**
* Iterative XML constructor
*
* @param array $array
* @param object|boolean $xml
* @return string
*/
function array2xml( $array, $xml = false) {
// Test if iteration
if ( $xml === false ) {
$key= key($array);
$xml = new SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><'.$key.'/>');
$array=$array[$key];
}
foreach( $array as $key => $value ) {
// Another array? Iterate
if ( is_array( $value ) ) {
if(!is_assoc_array($value)) {
foreach( $value as $skipkey => $childvalue )
array2xml( $childvalue, $xml->addChild( $key ) );
}
else {
array2xml( $value, $xml->addChild( $key ) );
}
} else {
$xml->addChild( $key, $value );
}
}
// Return XML
return $xml->asXML();
}
// Get The transformed XML
$data= $request->getPayload();
// Decode body (stdClass) to jSON to array
$jSON = json_decode(json_encode($data),true);
// Process array elements to XML
$xml = array2xml( $jSON, false );
Hey @mmaateurol thanks for the suggestion, can you provide a PR at the https://github.com/apioo/psx-data repository containing this change. In general this is of course a huge BC since this changes the XML output of every endpoint but if you provide a PR we can talk about this change.