Существует множество причин, по которым вы хотите создавать XML-документы с использованием PHP. Возможно, вы пишете свой собственный канал RSS или внедряете сервис REST . Вне зависимости от причины, это руководство познакомит вас с объектом DOMDocument и его использованием для создания динамических XML-документов.
Прежде чем мы начнем создавать настоящий XML, нам нужно что-то сделать из него. Я собираюсь начать с объявления класса, который будет содержать некоторую информацию о последних уроках здесь в Switch On The Code. Мы возьмем коллекцию этих объектов и создадим тот же XML, который был проанализирован jQuery в предыдущем уроке.
class Tutorial
{
public $author;
public $title;
public $date;
public $categories;
function __construct(
$author, $title, $date, $categories)
{
$this->author = $author;
$this->title = $title;
$this->date = $date;
$this->categories = $categories;
}
}
Здесь у нас есть очень простой объект PHP, который содержит различную информацию об учебнике — автор, название, дату публикации и категории. Давайте заполним массив из четырех таких объектов, которые мы затем преобразуем в XML.
$tutorials = array(
new Tutorial(
"The Reddest",
"Silverlight and the Netflix API",
"1/13/2009",
array(
"Tutorials",
"Silverlight 2.0",
"Silverlight",
"C#",
"XAML"
)
),
new Tutorial(
"The Hairiest",
"Cake PHP 4 - Saving and Validating Data",
"1/12/2009",
array(
"Tutorials",
"CakePHP",
"PHP"
)
),
new Tutorial(
"The Tallest",
"Silverlight 2 - Using initParams",
"1/6/2009",
array(
"Tutorials",
"Silverlight 2.0",
"Silverlight",
"C#",
"HTML"
)
),
new Tutorial(
"The Fattest",
"Controlling iTunes with AutoHotkey",
"12/12/2008",
array(
"Tutorials",
"AutoHotkey",
)
)
);
Теперь мы находимся в самой сути учебника — на самом деле строим некоторый XML.
header("Content-Type: text/plain");
//create the xml document
$xmlDoc = new DOMDocument();
//create the root element
$root = $xmlDoc->appendChild(
$xmlDoc->createElement("RecentTutorials"));
//make the output pretty
$xmlDoc->formatOutput = true;
echo $xmlDoc->saveXML();
Первая строка просто говорит браузерам, что я не возвращаю HTML, я просто возвращаю простой текст. Это препятствует тому, чтобы они пытались представить наш XML как HTML, который обычно не работает и дает вам пустой экран. Затем я создаю экземпляр DOMDocument . Конструктор принимает необязательную версию и кодировку, но по умолчанию он равен «1.0», что мне подходит. Далее я создаю корневой узел, который в моем случае есть RecentTutorials
. Я делаю это, создавая элемент с помощью функции createElement в DOMDocument и добавляя его как дочерний элемент в документ XML. Теперь я просто говорю DOMDocument отформатировать вывод, что делает его красивым, и отображать его на дисплее. Если мы запустим этот скрипт прямо сейчас, мы получим следующее:
<?xml version="1.0"?>
<RecentTutorials/>
Теперь давайте начнем заполнять наш XML информацией о руководствах. Мы начнем с простого создания Tutorial
тега и отображения автора в качестве атрибута, а заголовка и даты — в качестве дочерних элементов.
foreach($tutorials as $tut)
{
//create a tutorial element
$tutTag = $root->appendChild(
$xmlDoc->createElement("Tutorial"));
//create the author attribute
$tutTag->appendChild(
$xmlDoc->createAttribute("author"))->appendChild(
$xmlDoc->createTextNode($tut->author));
//create the title element
$tutTag->appendChild(
$xmlDoc->createElement("Title", $tut->title));
//create the date element
$tutTag->appendChild(
$xmlDoc->createElement("Date", $tut->date));
}
Сначала я создаю тег для учебника так же, как и корневой тег, за исключением того, что теперь я добавил его в качестве дочернего элемента к корневому элементу вместо документа XML. К сожалению, в отличие от createElement
, createAttribute
не имеет возможности принять значение в конструкторе. Это означает, что мы должны использовать очень подробный синтаксис для добавления атрибута к элементу. Сначала мы вызываем createAttribute и передаем ему желаемое имя, затем мы должны добавить значение атрибута в качестве дочернего, вызвав createTextNode и передав ему значение. После того, как мы создали атрибут, мы просто добавляем его в качестве дочернего к тегу учебника. Наконец, мы добавляем элементы для заголовка и даты, вызывая createElement и передавая имена и значения. Теперь у нас есть что-то похожее на это:
<?xml version="1.0"?>
<RecentTutorials>
<Tutorial author="The Reddest">
<Title>Silverlight and the Netflix API</Title>
<Date>1/13/2009</Date>
</Tutorial>
<Tutorial author="The Hairiest">
<Title>Cake PHP 4 - Saving and Validating Data</Title>
<Date>1/12/2009</Date>
</Tutorial>
<Tutorial author="The Tallest">
<Title>Silverlight 2 - Using initParams</Title>
<Date>1/6/2009</Date>
</Tutorial>
<Tutorial author="The Fattest">
<Title>Controlling iTunes with AutoHotkey</Title>
<Date>12/12/2008</Date>
</Tutorial>
</RecentTutorials>
Все, что осталось добавить, это категории. На самом деле мы уже видели все, что нам нужно, чтобы отобразить их, поэтому нужно просто просмотреть их и добавить элементы в документ.
//create the categories element
$catTag = $tutTag->appendChild(
$xmlDoc->createElement("Categories"));
//create a category element for each category in the array
foreach($tut->categories as $cat)
{
$catTag->appendChild(
$xmlDoc->createElement("Category", $cat));
}
И там у вас есть это. Теперь у нас есть полный XML-документ.
<?xml version="1.0"?>
<RecentTutorials>
<Tutorial author="The Reddest">
<Title>Silverlight and the Netflix API</Title>
<Date>1/13/2009</Date>
<Categories>
<Category>Tutorials</Category>
<Category>Silverlight 2.0</Category>
<Category>Silverlight</Category>
<Category>C#</Category>
<Category>XAML</Category>
</Categories>
</Tutorial>
<Tutorial author="The Hairiest">
<Title>Cake PHP 4 - Saving and Validating Data</Title>
<Date>1/12/2009</Date>
<Categories>
<Category>Tutorials</Category>
<Category>CakePHP</Category>
<Category>PHP</Category>
</Categories>
</Tutorial>
<Tutorial author="The Tallest">
<Title>Silverlight 2 - Using initParams</Title>
<Date>1/6/2009</Date>
<Categories>
<Category>Tutorials</Category>
<Category>Silverlight 2.0</Category>
<Category>Silverlight</Category>
<Category>C#</Category>
<Category>HTML</Category>
</Categories>
</Tutorial>
<Tutorial author="The Fattest">
<Title>Controlling iTunes with AutoHotkey</Title>
<Date>12/12/2008</Date>
<Categories>
<Category>Tutorials</Category>
<Category>AutoHotkey</Category>
</Categories>
</Tutorial>
</RecentTutorials>
И так, чтобы вы могли видеть все в одном месте, вот окончательное содержание скрипта PHP:
class Tutorial
{
public $author;
public $title;
public $date;
public $categories;
function __construct(
$author, $title, $date, $categories)
{
$this->author = $author;
$this->title = $title;
$this->date = $date;
$this->categories = $categories;
}
}
//make some tutorial objects
$tutorials = array(
new Tutorial(
"The Reddest",
"Silverlight and the Netflix API",
"1/13/2009",
array(
"Tutorials",
"Silverlight 2.0",
"Silverlight",
"C#",
"XAML"
)
),
new Tutorial(
"The Hairiest",
"Cake PHP 4 - Saving and Validating Data",
"1/12/2009",
array(
"Tutorials",
"CakePHP",
"PHP"
)
),
new Tutorial(
"The Tallest",
"Silverlight 2 - Using initParams",
"1/6/2009",
array(
"Tutorials",
"Silverlight 2.0",
"Silverlight",
"C#",
"HTML"
)
),
new Tutorial(
"The Fattest",
"Controlling iTunes with AutoHotkey",
"12/12/2008",
array(
"Tutorials",
"AutoHotkey",
)
)
);
//create the xml document
$xmlDoc = new DOMDocument();
//create the root element
$root = $xmlDoc->appendChild(
$xmlDoc->createElement("RecentTutorials"));
foreach($tutorials as $tut)
{
//create a tutorial element
$tutTag = $root->appendChild(
$xmlDoc->createElement("Tutorial"));
//create the author attribute
$tutTag->appendChild(
$xmlDoc->createAttribute("author"))->appendChild(
$xmlDoc->createTextNode($tut->author));
//create the title element
$tutTag->appendChild(
$xmlDoc->createElement("Title", $tut->title));
//create the date element
$tutTag->appendChild(
$xmlDoc->createElement("Date", $tut->date));
//create the categories element
$catTag = $tutTag->appendChild(
$xmlDoc->createElement("Categories"));
//create a category element for each category in the array
foreach($tut->categories as $cat)
{
$catTag->appendChild(
$xmlDoc->createElement("Category", $cat));
}
}
header("Content-Type: text/plain");
//make the output pretty
$xmlDoc->formatOutput = true;
echo $xmlDoc->saveXML();
В целом, процесс создания XML-документов в PHP кажется мне довольно многословным, особенно по сравнению с использованием объекта .NET XDocument . Помимо этого, он все еще очень простой, мощный и, безусловно, выполняет свою работу.