Search

A new extension, "APIPage" is now available for download. Comments and feedback can be left here but if you discover any issues, please post it on the issue tracker.

What do you mean by "Generate api pages"?

What does this extension actually do?

Right now it gives you the ability to output your page weather as xml or json depending on the url parameter which you can set on the extensions preferences. Sure, You can also do this by using a xmltojson xsl utility, but to be honest: they all have issues.

The included xmlto(json|array) parser produces an almost complete set of data of your xml (including attributes) and since it uses the SimpleXML extension its also quite fast.

Right now it gives you the ability to output your page weather as xml or json depending on the url parameter which you can set on the extensions preferences.

Ah, cool. A little hint in the description would be nice, though... ;)

The included xmlto(json|array) parser produces an almost complete set of data of your xml (including attributes) and since it uses the SimpleXML extension its also quite fast.

So I basically create my output as xml like usual, but instead of setting the page type to xml, I set it to api and my xml gets converted to json automatically?

Yes, though you can specify the default output to be xml or json. Given you have set format parameter to url-format, you can trigger the outputformat like http://myapi.com/api/foo?format=json. This could also be a Page URL Parameter. As long as it exists in the page parameter pool it will work. apipage prefs

Nice.

Just in case you didn't already know, Jonas has another very interesting extension (Content Negotiation) for API stuff that supports more formats, but doesn't convert things automatically (provides different templates for each format instead that you have to write manually).

That's nice, indeed. But with regards to the transformation from xml to json or any other dataformat, I think xslt is not the best way to do it (at least not xslt 1.0).

In this special case, I needed a reliable and tested xml to array parser, the whole extension around is just sugar :)

I was discussing JSON from XSLT with Brendan while he was in London. JSON from PHP arrays and Objects is much cleaner, using built in functions.

There are projects that do JSON from XSLT as we've both discussed before, but they're never solid enough for me.

I will definitely be looking at this extension soon.

APIPage updated to version 0.1.3 on 4th of January 2013

APIPage updated to version 0.1.4 on 5th of January 2013

AWSM. There is just one issue: if you have an xml structure like this:

<reponse>
    <status>ok</status>
    <entries>
        <entry>
            <title>post 1</title>
        </entry>
        <entry>
            <title>post 2</title>
        </entry>
    </entries>
</response>

then entry number 1 is left out. This issue is caused by lib/xmltoarray.php around line 73; the array created earlier is always overwritten, rather than concatenated to.

After trying to fix this for a while, I finally found a solution, but you aren't going to like it...

Basically the entire xmltoarray class is redundant, as SimpleXML allows casting to array, and you can just pass the SimpleXML object to thejson_encode function.

Ouch.

@creativedutchme I know this, one could simply do json_decode(json_encode((array)$xmlOBJ), true);, but there is a problem with this approach: you can't get attributes on complete elements.

Consider the following:

 <?xml version="1.0" encoding="UTF-8"?>
 <response>
     <status code="200">ok</status>
 <entries>
      <entry id="1">
          <title handle="post-1">post 1</title>
       </entry>
       <entry id="2">
          <title handle="post-2">post 2</title>
           </entry>
      </entries>
  </response>

would result in:

Array
(
    [status] => ok
    [entries] => Array
        (
            [entry] => Array
                (
                    [0] => Array
                        (
                            [@attributes] => Array
                                (
                                    [id] => 1
                                )
                        [title] => post 1
                    )

                [1] => Array
                    (
                        [@attributes] => Array
                            (
                                [id] => 2
                            )

                        [title] => post 2
                    )

            )

    )

)

I'll check the issue you mentioned.

BTW, your XML is invalid :)

EDIT: just had a look, you xml will correctly output:

    {"response": {
        "status":"ok",
            "entries":{
                "entry": [ 
                     {"title":"post 1"},
                     {"title":"post 2"}
                ]
            }
        }
    }
 

Hmm, that's odd.

Can you please try my full xml, just to see what happens?

<?xml version="1.0" encoding="UTF-8"?>
<response>
  <status>ok</status>
  <boekrecensies>
    <pagination total-entries="5" total-pages="3" entries-per-page="2" current-page="1"/>
    <entry id="488">
      <titel>
        <value>Future Practice. Conversations from the edge of architecture</value>
        <handle>future-practice-conversations-from-the-edge-of-architecture</handle>
      </titel>
      <thumbnail>
        <afbeelding>/uploads/future_practice_thumbnail_400-50ccbe2648169.jpg</afbeelding>
        <bijsnijden>2</bijsnijden>
      </thumbnail>
    </entry>
    <entry id="518">
      <titel>
        <value>Afterlives of Neoliberalism</value>
        <handle>afterlives-of-neoliberalism</handle>
      </titel>
    </entry>
  </boekrecensies>
</response>

The expected JSON is something along these lines:

{
  "status": "ok",
  "boekrecensies": {
    "pagination": {
      "@attributes": {
        "total-entries": "5",
        "total-pages": "3",
        "entries-per-page": "2",
        "current-page": "1"
      }
    },
    "entry": [
      {
        "@attributes": {
          "id": "488"
        },
        "titel": {
          "value": "Future Practice. Conversations from the edge of architecture",
          "handle": "future-practice-conversations-from-the-edge-of-architecture"
        },
        "thumbnail": {
          "afbeelding": "/uploads/future_practice_thumbnail_400-50ccbe2648169.jpg",
          "bijsnijden": "2"
        }
      },
      {
        "@attributes": {
          "id": "518"
        },
        "titel": {
          "value": "Afterlives of Neoliberalism",
          "handle": "afterlives-of-neoliberalism"
        }
      }
    ]
  }
}

but the actual output is:

{
  "response": {
    "status": "ok",
    "boekrecensies": {
      "pagination": {
        "@attributes": {
          "total-entries": "5",
          "total-pages": "3",
          "entries-per-page": "2",
          "current-page": "1"
        }
      },
      "entry": {
        "@attributes": {
          "id": "518"
        },
        "titel": {
          "value": "Afterlives of Neoliberalism",
          "handle": "afterlives-of-neoliberalism"
        }
      }
    }
  }
}

yea, right, this clearly is a bug. A temporary sulution is to wrap the entry tags in a parent object.

For now I've fixed it with json_encode'ing the SimpleXML object directly, and keeping the limitation in my head (hence the seperate value and handle tags in the xml).

Just for reference, the Zend framework has a (rather good) XML to JSON class that you can use, if you can't be bothered to spend more time on this ;)

I've debugged the shit out of it right now…

the Zend\Json\Json::fromXml() looks great indeed.

I think I have fixed it. Tests are passing with your example.

APIPage updated to version 0.1.5 on 15th of January 2013

APIPage updated to version 0.1.6 on 3rd of February 2013

various bugfixes:

  • fix empty nodes
  • fix nodes with mixed content (text and childnodes)
  • textnodes with attributes no longer returns node: {@attributes: {...}, value: text} but node: {@attributes: {...}, text: text}

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