У меня есть сценарий, который собирает 4 URL (XML) с использованием CURL и возвращает массив с 4 элементами, каждый из которых получает результаты URL.
Вот массив:
array(3) { [0]=> string(41772) "<?xml version="1.0" encoding="UTF-8"?> <statuses type="array"> <status> <created_at>Tue Mar 30 20:58:53 +0000 2010</created_at> <id>11328253513</id> <text>...</text> <source...</source> <truncated>false</truncated> <in_reply_to_status_id></in_reply_to_status_id> <in_reply_to_user_id></in_reply_to_user_id> <favorited>true</favorited> <in_reply_to_screen_name></in_reply_to_screen_name> <user> <id>1...</id> <name>....</name> </status> </statuses> " [1]=> string(20630) "<?xml version="1.0" encoding="UTF-8"?> <statuses type="array"> <status> <created_at>Sun Feb 28 14:12:30 +0000 2010</created_at> <id>...</id> <text>...</text> <source><a etc...
Как я могу легко вывести XML из массива? Мне также необходимо объединить 3 структуры XML в один, где <statuses>
начинается и заканчивается между каждым массивом.
Для простого слияния, подобного этому, вы также можете просто сделать:
$xml = implode('', $theArray); $xml = str_replace(array('<?xml version="1.0" encoding="UTF-8"?>', '<statuses type="array">', '</statuses>'), '', $xml); $xml = '<?xml version="1.0" encoding="UTF-8"?>' . '<statuses type="array">' . $xml . '</statuses>';
Примечание: непроверенный, но в основном все, что он делает, – это склеить все XML-документы в один, а затем удалить XML-прологи и все корневые узлы, поэтому остаются только узлы состояния. Затем они снова завертываются в действительный скелет XML, например, пролог и корневой узел. Готово.
Если впоследствии вы захотите работать с узлами DOM, использование DOM будет более надежным, поскольку DOM знает, что такое узлы, тогда как строковые функции не имеют понятия о них. Если вы решили работать с DOM, подумайте о загрузке документов с загрузкой вместо CURL, как показано в примере Pascal, или используйте вышеприведенное, а затем загрузите этот документ из строки с помощью loadXml () .
Независимо от того, что вы решили использовать, не используйте Regex. Это путь к безумию.
Возможная идея:
$destination
DOMDocument
<statuses>
DOMDocument
: $currentDocument
<status>
, с $currentDocument->getElementsByTagName
или эквивалентным <status>
вы только что нашли в $destination
документе $destination->importNode
, с $destination->importNode
$destination
должен содержать то, что вы хотели, и вы можете сохранить его, используя $destination->saveXML
И вот краткий пример кода, который поможет вам понять, что я имел в виду:
Во-первых, вот массив строк XML – я сделал их намного короче, но идея та же, что и у вас:
$strings = array( '<?xml version="1.0" encoding="UTF-8"?> <statuses type="array"><status> <id>ID 1</id> </status></statuses>', '<?xml version="1.0" encoding="UTF-8"?> <statuses type="array"><status> <id>ID 2</id> </status></statuses>', '<?xml version="1.0" encoding="UTF-8"?> <statuses type="array"><status> <id>ID 3</id> </status></statuses>', );
Давайте создадим документ назначения и поместим в него <statuses>
:
$destination = new DOMDocument(); $destination->formatOutput = true; $destinationStatuses = $destination->createElement('statuses'); $destination->appendChild($destinationStatuses);
Теперь мы перебираем три строки XML:
foreach ($strings as $str) { $current = new DOMDocument(); $current->loadXML($str); $currentStatuses = $current->getElementsByTagName('status'); foreach ($currentStatuses as $currentStatus) { $destinationStatus = $destination->importNode($currentStatus, true); $destinationStatuses->appendChild($destinationStatus); } }
Для каждой строки мы:
DOMDocument
<status>
<status>
импортируйте его в целевой документ <statuses>
И, наконец, если мы выводим содержимое нового документа:
echo '<pre>' . htmlspecialchars($destination->saveXML()) . '</pre>';
Мы получаем :
<?xml version="1.0"?> <statuses> <status> <id>ID 1</id> </status> <status> <id>ID 2</id> </status> <status> <id>ID 3</id> </status> </statuses>
т.е. наши три <status>
из трех исходных строк были объединены в один XML-документ 😉