Я дал обширный пример в вопросе PHP simplexml xpath search for value in an ELEMENT containing tab delimited text?, который показывает, как можно манипулировать SimpleXMLElement на лету, содержащего закодированные данные, превращая его в более доступных данных.
Это можно сделать аналогичным образом в вашем случае, однако на этот раз я хотел бы показать, как это можно сделать с помощью пользовательских итераторов.
Но сначала рассмотрим, как можно представить таблицу: Таблица состоит из строк и столбцов. Таким образом, мы могли выполнять итерацию по строкам, и каждая строка могла быть итератором столбцов.
И с вашим вопросом, есть и другой итератор над таблицами. Поэтому в псевдокоде это может выглядеть так:
foreach($tables as $table)
{
foreach ($table as $rows) {
foreach ($rows as $column) {
}
}
}
Выполнение вывода где-то вокруг этого. Так, например, если у нас есть Итератор, способный перебирать строки и столбцы, чтобы преобразовать их в таблицу (например, как обычный текст для демонстрационных целей), псевдокод можно свести к следующему:
foreach($tables as $table)
{
echo new TextTable($table);
}
Как показано на этом примере, проблема уже была уменьшена, чтобы отобразить одну таблицу, поскольку все таблицы соответствуют одной и той же структуре. Сейчас я не показываю TextTable
, но это не является дополнительным интересом. Если вы ищете итератор, который выводит таблицу HTML, следуя той же итерации, см. Связанный вопрос выше, он имеет HtmlTableIterator
, который выполняет большую часть работы. Но прямо сейчас давайте посмотрим, как создать итератор по строкам и столбцам.
Для этого я представляю вам существующий класс итератора с именем DecoratingIterator
. Он позволяет украшать каждый элемент текущего на итерации. Это довольно гибко, потому что мы можем использовать его для составления финального итератора таблицы довольно гибким способом с небольшими шагами.
Решите все проблемы, с которыми вы сталкиваетесь, шаг за шагом. Прежде всего, нужна функция, чтобы превратить число 0 в пустую строку. Давайте создадим функцию для этого (и я также добавить еще некоторое форматирование предваряя с пробелами, если это необходимо, чтобы получить длину двух):
$formatNumber = function($number)
{
if ($number === '0') {
$number = '';
}
return sprintf("%' 2s", $number);
};
Следующая задача решить это превратить SimpleXMLElement
чисел в нечто Еогеасп которые являются форматированными числами.Давайте просто писать, а также и использовать предыдущей функции, чтобы помочь сделать это:
$numbersToArray = function($stringNumbers) use ($formatNumber) {
return array_map($formatNumber, explode('-', $stringNumbers));
};
Вау, это было коротким. Следующая задача для решения состоит в том, чтобы превратить все строки одной таблицы в эти массивы чисел. Ну, опять же, мы делаем это с помощью последней функции:
$tableToRows = function(SimpleXMLElement $table) use ($numbersToArray) {
return new DecoratingIterator($table->children(), $numbersToArray);
};
И, наконец, одна проблема остается: Весь XML должен быть превращена в итератор всех таблиц. Снова с предыдущей функцией это снова стало проще:
$tables = new DecoratingIterator(
$xml->message->ticketpage->ticket,
$tableToRows
);
Ничего себе. Возможно, немного долго, давайте обзор:
$formatNumber = function($number)
{
if ($number === '0') {
$number = '';
}
return sprintf("%' 2s", $number);
};
$numbersToArray = function(SimpleXMLElement $stringNumbers) use ($formatNumber) {
return array_map($formatNumber, explode('-', $stringNumbers));
};
$tableToRows = function(SimpleXMLElement $table) use ($numbersToArray) {
return new DecoratingIterator($table->children(), $numbersToArray);
};
$tables = new DecoratingIterator(
$xml->message->ticketpage->ticket,
$tableToRows
);
Все эти строки кода сделать, это обеспечить $tables
итератора можно использовать для отображения таблицы. Таким образом, чтобы сделать это более легкий в использовании, мы обернуть это в класс его собственного и сигналом PHP, что этот класс может агрегировать итератор, который работает через интерфейс IteratorAggregate
:
class TableAggregator implements IteratorAggregate
{
private $xml;
public function __construct(SimpleXMLElement $xml)
{
$this->xml = $xml;
}
public function getIterator()
{
# ... code to create the tables iterator
return $tables;
}
}
Хорошо, что, вероятно, было много до сих пор. Лучше показать пример использования-сейчас, чтобы сделать видимой почему агрегация имеет смысл здесь:
$xml = simplexml_load_file('example.xml');
$tables = new TableAggregator($xml);
foreach ($tables as $table) {
echo new TextTable($table), "\n";
}
Как показывает этот пример, его, потому что это простой в использовании. Также, если у нас есть другие потребности в форматировании, мы могли бы создать другой aggregator - это просто. Давайте посмотрим примерный вывод:
+--+--+--+--+--+--+--+--+--+
| |10|27|30|45| | | |80|
+--+--+--+--+--+--+--+--+--+
| |15| |38| |51|62| |85|
+--+--+--+--+--+--+--+--+--+
| 5| | |37| |57|60|77| |
+--+--+--+--+--+--+--+--+--+
+--+--+--+--+--+--+--+--+--+
| | |20|33| |56|68| |90|
+--+--+--+--+--+--+--+--+--+
| 8| | | |49| |64|71|84|
+--+--+--+--+--+--+--+--+--+
| 1|18|22|32| |59| | | |
+--+--+--+--+--+--+--+--+--+
+--+--+--+--+--+--+--+--+--+
| | |23| |47|58|67| |86|
+--+--+--+--+--+--+--+--+--+
| 4|16| | |43|53| | |88|
+--+--+--+--+--+--+--+--+--+
| 3| |28|35| | |65|72| |
+--+--+--+--+--+--+--+--+--+
+--+--+--+--+--+--+--+--+--+
| |19|26| |48|52| |74| |
+--+--+--+--+--+--+--+--+--+
| | |21| |40| |63|75|82|
+--+--+--+--+--+--+--+--+--+
| 9|11| |34|41| | |76| |
+--+--+--+--+--+--+--+--+--+
+--+--+--+--+--+--+--+--+--+
| |12|29|36|44| | |78| |
+--+--+--+--+--+--+--+--+--+
| 6|14| |39| | |69| |89|
+--+--+--+--+--+--+--+--+--+
| 2| | | | |54|66|70|81|
+--+--+--+--+--+--+--+--+--+
+--+--+--+--+--+--+--+--+--+
| |17|25| |46| | |73|87|
+--+--+--+--+--+--+--+--+--+
| | |24| |42|50|61|79| |
+--+--+--+--+--+--+--+--+--+
| 7|13| |31| |55| | |83|
+--+--+--+--+--+--+--+--+--+
Весь пример одного взгляда: https://gist.github.com/hakre/5734770
Общий учебник о SimpleXMLElement можно найти здесь: http://php.net/simplexml.examples-basic - вы начинаете с этим, написав некоторый код, загружающий XML-документ. Затем вы разбираете его, как правило, итерацией по нему. – hakre