Search

Hi, I am trying to return a php array in custom remote datasource.

Looking at others remote datasource classes, i tried to return $data = print_r($data, true); as a text. So I can see my php array of data in the xml output. Php class looks like that:

Class CUSTOMFormatter implements Transformer
{
    public function accepts()
    {
        return 'text/plain, */*';
    }
    public function transform($data)
    {
    [...]
    $data = print_r($data, true);
    $txtElement = new XMLElement('entry');
    $txtElement->setValue(General::wrapInCDATA($data));
    $data = $txtElement->generate();
    return $data;
    }
 }

Resulting the xml:

<remote-ds status="fresh" ...>
<entry>Array {
         [a] =&gt; 1
         [b] =&gt; 2
         [c] =&gt; 3
         [É] =&gt; 0.004
}
</entry>
</remote-ds>

Then i tried to apply the class Array2XML on my $data variable, and output as a xml instead of text. But I always get a "Invalid Character Error" in my xml entry.

Php:

Class CUSTOMFormatter implements Transformer
{
    public function accepts()
    {
        return 'text/xml, */*';
    }
    public function transform($data)
    {
    [...]
    $data = Array2XML::createXML('data', $data);
    if (!General::validateXML($data, $errors, false, new XsltProcess)) {
        throw new TransformException('Data returned is invalid.', $errors);
    }
    return $data;
    }
 }

Result:

<remote-ds url="..." ...>
   <error>Invalid Character Error</error>
</remote-ds>

Is it because the $data array contains Éà characters? Any Idea of what I should do to make it works?

Solved via a php array to JSON, my final php:

Class CUSTOMFormatter implements Transformer
{
    public function accepts()
    {
        return 'application/json, */*';
    }
    public function transform($data)
    {
    [...]
    $data = json_encode($data, JSON_PRETTY_PRINT);
    try {
        $data = JSON::convertToXML($data);
    } catch (Exception $ex) {
        throw new TransformException($ex->getMessage(), array(
            'message' => $ex->getMessages()
        ));
    }
    return $data;
    }
 }

If you have an idea on how to turn the php array into xml, instead of json then xml, I will be happy read it!

The core has a method that may be of use to you, General::array_to_xml

Hi Brendo, thanks for the info! I tryed :

$data = General::array_to_xml('entry', $data);

and

$xml = new XMLElement('entry');
$xml->setValue(General::array_to_xml($data));
$data = $xml->generate();

before "return $data;" but both give me "Argument 1 passed to General::arraytoxml() must be an instance of XMLElement, string given".

I am not familiar with php, so I don't know how to use the method...

Hi Vincent use the below

$xml->appendChild(General::array_to_xml($data))

setValue expects a string, whilst appendChild appends an XML Element inside another. Which is what you want to do.

Thanks Jonathan for the help, so I tried:

$xml = new XMLElement('entry');
$xml->appendChild(General::array_to_xml($data));
$data = $xml->generate();

and it gives me "Argument 1 passed to General::arraytoxml() must be an instance of XMLElement, array given" so I assume the $data is not read as an array (perhaps strange when you see the result of the print_r in my previous tests). Do you think I have to escape special characters of the array before?

Looking at your previous code you have this : $data = print_r($data, true); does that still exist?

Because that is converting your $data array into a string. If it's still there can you remove that line and try again?

Both close, but try this:

$entry = new XMLElement('entry');
General::array_to_xml($entry, $data);
$xml = $entry->generate();

From the docs:

Parameters

$parent XMLElement the XML element to append the formatted array data to. $data array the array to format and append to the XML fragment.

Thanks Brendo it works! But... I got an issue with the data. Encoding to json then xml keeps more infos from the array, here is the format of the php array (given buy the print_r) :

Array {
       [singleword] => 1
       [composed name sometimes] => 2
       [with special çhàracters] => 00.3
}

So with the following json workaround:

$data = json_encode($keywords, JSON_PRETTY_PRINT);
$data = JSON::convertToXML($data);

datasource output look like this:

<remote-ds url="..." ...>
   <data>
       <singleword handle="singleword" value="single word">1</singleword>
       <key handle="composed-name-sometimes" value="composed name sometimes">2</key>//node: key for composed text
       <key handle="with-special-characters" value="with special çhàracters">00.3</key>
   </data>
</remote-ds>

and with the core method General::arraytoxml($entry, $data); the datasource looks like this:

<remote-ds url="..." ...>
   <data>
       <singleword>1</singleword>
       <composed-name-sometimes>2</key>
       <with-special-characters>00.3</key>
   </data>
</remote-ds>

So with I loose the space and special characters, in fact it will be perfect if I find a way to invert the rows and columns of the array. It will makes more sense in regard of the nature of data to output to have a xml like that:

<remote-ds url="..." ...>
   <data>
       <1>singleword</1>
       <2>composed name sometimes</2>
       <00.3>with special çhàracters</00.3>// or even 003 or 3, I don't mind
   </data>
</remote-ds>

I tried to arrayflip($data) but I get the error "arrayflip(): Can only flip STRING and INTEGER values!". So I have to find a way to convert values from decimal to integer, I will dig in that way or stay with the json workaround.

Thank you very much for your help! (and sorry for the long post :-p)

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details