I'm trying to create a dynamic table based on an XML. The outputted XML is the following:
<tickets xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<status>1</status>
<message>
<ticketpage>
<ticket>
<row1>0-10-27-30-45-0-0-0-80</row1>
<row2>0-15-0-38-0-51-62-0-85</row2>
<row3>5-0-0-37-0-57-60-77-0</row3>
</ticket>
<ticket>
<row1>0-0-20-33-0-56-68-0-90</row1>
<row2>8-0-0-0-49-0-64-71-84</row2>
<row3>1-18-22-32-0-59-0-0-0</row3>
</ticket>
<ticket>
<row1>0-0-23-0-47-58-67-0-86</row1>
<row2>4-16-0-0-43-53-0-0-88</row2>
<row3>3-0-28-35-0-0-65-72-0</row3>
</ticket>
<ticket>
<row1>0-19-26-0-48-52-0-74-0</row1>
<row2>0-0-21-0-40-0-63-75-82</row2>
<row3>9-11-0-34-41-0-0-76-0</row3>
</ticket>
<ticket>
<row1>0-12-29-36-44-0-0-78-0</row1>
<row2>6-14-0-39-0-0-69-0-89</row2>
<row3>2-0-0-0-0-54-66-70-81</row3>
</ticket>
<ticket>
<row1>0-17-25-0-46-0-0-73-87</row1>
<row2>0-0-24-0-42-50-61-79-0</row2>
<row3>7-13-0-31-0-55-0-0-83</row3>
</ticket>
</ticketpage>
</message>
</tickets>
Each "ticket" is a new table, each "row" is a row and each number in the row is a column (except for the 0, that will be an empty cell).
I know I should be using PHP's SimpleXML, but I have no idea how.
How do I go about doing this?
You can try this:
I've given an extensive example in the question PHP simplexml xpath search for value in an ELEMENT containing tab delimited text? that shows how you can manipulate a SimpleXMLElement on-the-fly containing encoded data turning it into more accessible data.
This could be done similarly in your case, however this time I'd like to to show how this can be done with custom iterators.
But first let's consider how a table could be represented: A table consists of rows and columns. So we could iterate over rows and each row could be an iterator of columns.
And with your question, there is also another iterator over the tables. So in pseudo-code this can look like:
Doing the output somewhere around that. So for example, if we have got an Iterator that is able to iterate over rows and columns that way to convert is into a table (for example as plain text for demonstration purposes so far), the pseudo-code can be reduced to this:
As this example shows, the problem has been already reduced to display a single table - because all tables follow the same structure. I do not show
TextTable
works right now, it's not of further interest. If you are looking for an iterator that outputs a HTML table following the same iteration, see the linked question above, it has got aHtmlTableIterator
which does most of the work. But right now, let's look how to create the iterator over rows and columns.For that I introduce you to an existing iterator class named
DecoratingIterator
. It allows to decorate each current element in an iteration. This is pretty flexible because we can use it to compose the final table-iterator in a pretty flexible way in small steps.Let's solve all the problems you face, step by step. First of all a function is needed to turn the number 0 into an empty string. Let's create a function for that (and I also add some more formatting by prefixing with spaces if necessary to get a length of two):
The next problem to solve is to turn the
SimpleXMLElement
of numbers into something foreach-able that are those formatted numbers. Let's just write it as well and use the previous function to help get it done:Wow, that was short. The next problem to solve is to turn all rows of a single table into these array of numbers. Well, again, we do it with the help of the last function:
And finally one problem is left: The whole XML needs to be turned into an iterator of all the tables. Again with the previous function this is more easy again:
Wow. Probably a bit long, let's review:
All these lines of code do is to provide the
$tables
iterator we can use to display the tables. So to make this more easy to use, we wrap this into a class of it's own and signal PHP that this class can aggregate an iterator which works via theIteratorAggregate
interface:Okay, that probably was a lot so far. Better show the usage-example now to make visible why aggregation makes sense here:
As this example shows, its because this is easy to use. Also if we have a different formatting needs, we could create a different aggregator - that simple it is. Let's see the exemplary output:
The whole example at a glance: https://gist.github.com/hakre/5734770