Создавайте XML-документ с помощью PHP простым способом

Я хочу создать XML-документ в PHP.

Я выбрал DOMDocument, и я знаю, что мне нужно использовать такие методы, как createElement, createTextNode, appendChild и т. д., чтобы построить мой XML.

Вот как я сгенерировал xml только с одним узлом, содержащим информацию о транспортном средстве:

<?php
$doc = new DOMDocument ( '1.0', 'utf-8' );
$vehicles = $doc->createElement ( "Vehicles" );

$vehicle = $doc->createElement("Vehicle");
$vehicle_num = $doc->createElement("Number");
$vehicle_desc = $doc->createElement("Description");
$vehicle_year = $doc->createElement("Year");
$vehicle_make = $doc->createElement("Make");
$vehicle_model = $doc->createElement("Model");
$vehicle_color = $doc->createElement("Color");

$vehicle_num->appendChild($doc->createTextNode("AW2CM31Y8"));
$vehicle_year->appendChild($doc->createTextNode("2013"));
$vehicle_make->appendChild($doc->createTextNode("VOLKSWAGEN"));
$vehicle_model->appendChild($doc->createTextNode("NEW BEETLE"));
$vehicle_color->appendChild($doc->createTextNode("Black"));

$vehicle_desc->appendChild($vehicle_year);
$vehicle_desc->appendChild($vehicle_make);
$vehicle_desc->appendChild($vehicle_model);
$vehicle_desc->appendChild($vehicle_color);

$vehicle->appendChild($vehicle_num);
$vehicle->appendChild($vehicle_desc);

$vehicles->appendChild($vehicle);
$doc->appendChild ( $vehicles );

header ( "Content-type: text/xml" );
echo $doc->saveXML ();

Но что, если я хочу создать xml, скажем, со 100 узлами, содержащими не только информацию о транспортном средстве, но и другие узлы выше и ниже него. Этот процесс был бы слишком трудоемким.

Итак, есть ли простой способ создания узлов и добавления к ним значений в xml с помощью php? Меня беспокоит количество строк кода, которые я должен написать.


person shasi kanth    schedule 31.10.2013    source источник
comment
Я не уверен, что термин оптимистичный подходит для такого технического вопроса, как ваш. XML - это просто формат сериализации, поэтому вместо того, чтобы писать создание только как код, вы должны прежде всего разделить данные на собственную структуру данных. Затем напишите код, который создает XML на основе структуры данных. Это лучший совет, который я могу честно дать.   -  person hakre    schedule 31.10.2013
comment
@hakre Изменил мой вопрос сейчас.   -  person shasi kanth    schedule 31.10.2013
comment
Вы можете написать это как обычный xml? Или, если у вас есть источник данных для экспорта в виде XML, используйте цикл for (каждый)?   -  person TiMESPLiNTER    schedule 31.10.2013
comment
Ну, я уже понял это так, однако все еще остается неопределенным, что было бы на самом деле легко в вашем случае. Возможно, вы хотели бы знать, как можно предотвратить повторение дублирующегося кода. Это, пожалуй, гвозди.   -  person hakre    schedule 31.10.2013
comment
@hakre Вы меня поняли. Я хочу предотвратить дублирование кода. Только для создания одного узла в xml я пишу около 3 строк кода. (Создать узел, добавить значение, добавить к другому узлу). Я хочу минимизировать количество строк кода.   -  person shasi kanth    schedule 31.10.2013
comment
Я оставил вам подробный ответ. Для журнала: createElement уже может принимать текст в качестве значения (рядом с тэгом), поэтому вам не нужно создавать такой подробный текстовый узел. Вы также можете использовать SimpleXML, а затем передать его DOMDocument. Однако ответ делает это по-другому, что может дать вам больше информации о том, как решить (с помощью вашего компьютера) общую проблему, стоящую за вашей проблемой.   -  person hakre    schedule 31.10.2013


Ответы (3)


Первое, что приходит на ум, это то, что у вас есть повторение кода. Возможно, вы хотите уменьшить это. Это можно сделать, переместив повторяющийся код в собственную функцию.

Чтобы сделать это быстро, в PHP есть замыкания. Давайте выстроим это:

У вас есть коллекция транспортных средств, и у каждого транспортного средства есть только свойства и значения. Таким образом, вы добавляете свойство к транспортному средству. Кстати, createElement уже принимает текст как значение, поэтому вам не нужно создавать текстовые узлы. Итак, давайте обернем повторяющийся код в функции, а затем просто вызовем эти функции для создания XML. Это уже - через параметризацию - показывает вашу структуру. Просто различайтесь между определениями функций (первая часть) и их применением (вторая часть):

<?php
/**
 * Create XML Document with PHP in an easy way
 *
 * @link http://stackoverflow.com/q/19702911/367456
 */

/**
 * @param DOMNode $node
 * @return DOMDocument
 */
$doc = function (DOMNode $node = NULL) {
    return $node ? ($node->ownerDocument ? : $node) : new DOMDocument();
};

/**
 * @param DOMElement $element
 * @param string $property
 * @param string $text
 * @return DOMElement the element the proeprty was added to
 */
$prop = function (DOMElement $element, $property, $text) {
    return $element->appendChild(
        $element->ownerDocument->createElement($property, $text)
    );
};

/**
 * @param DOMNode $element
 * @param string $name
 * @return DOMElement
 */
$element = function (DOMNode $element, $name) use ($doc) {
    return $element->appendChild(
        $doc($element)->createElement($name)
    );
};

Итак, после того, как все эти функции были определены, переходим ко второй части:

$prop(
    $vehicle = $element(
        $vehicles = $element(
            $doc()
            , 'Vehicles'
        )
        , 'Vehicle'
    )
    , "Number"
    , "AW2CM31Y8"
);

$prop(
    $vehicle
    , "Year"
    , "2013"
);

$prop(
    $vehicle
    , "Make"
    , "VOLKSWAGEN"
);

$prop(
    $vehicle
    , "Model"
    , "NEW BEETLE"
);

$prop(
    $vehicle
    , "Color"
    , "Black"
);

И вуаля. Это выявило некоторую структуру. Дублирование кода также было удалено. Осталось только вывести результат:

header("Content-type: text/xml");
echo $doc($vehicles)->saveXML();

Если вы посмотрите на код, вы даже можете прочитать, что он буквально переворачивает структуру данных для создания XML. Итак, следующим шагом будет использование какого-то обхода, но для этого сначала нужно определить структуру данных, а не только определение структуры кода, как это было сделано до сих пор (и которое уже должно быть полезно для тебя).

Онлайн-пример: https://eval.in/59090

person hakre    schedule 31.10.2013
comment
@dskanth: не удаляйте символы новой строки / отступы в этом примере кода ответов, поскольку он фактически показывает структуру. Вы можете найти это многословным, я использую это, чтобы сделать это более заметным. Позаботьтесь о том, чтобы этот код/структура на самом деле был промежуточным этапом, поскольку у вас еще нет структуры данных. - person hakre; 31.10.2013
comment
Ничего страшного. Спасибо за ответ. Работает хорошо. - person shasi kanth; 31.10.2013
comment
Что ж, обычно предлагается выполнить преобразование массива в XML, чтобы вы могли еще больше уменьшить дублирование кода, расширенный пример, который также может обновлять структуры XML: Как обновить SimpleXMLElement с помощью массива — имейте в виду, что пример не такой подробный. - person hakre; 31.10.2013
comment
Расширяя ответ hakre, если вам нужно добавить атрибут к узлам в xml, используйте этот код: $attr = function (DOMElement $element, $property, $attribute, $attribute_value, $text) { $elem = $element-›ownerDocument-›createElement($property, $text); $elem-›setAttributeNode(новый DOMAttr($attribute, $attribute_value)); вернуть $element-›appendChild($elem); }; Использование: $attr($vehicle, Year, month, 06, 2013); - person shasi kanth; 05.11.2013

Мне кажется, что вы действительно ищете XML-сериализацию объекта с некоторым контролем над созданным в нем документом.

С этой целью вы можете посмотреть проект XMLSerializer — https://bitbucket.org/schmijos/xmlserializer

Который возьмет массив/объект PHP и сериализует его в XML.

person Tim Ebenezer    schedule 31.10.2013
comment
Спасибо за ссылку.. выглядит полезно - person shasi kanth; 31.10.2013

Я рекомендую вам создать XML с той же структурой и использовать его в качестве шаблона. Так что вам нужно только заполнить этот xml.

person Alex Kapustin    schedule 31.10.2013