Данные, хранящиеся в XML файле, можно редактировать прямо в клиентском браузере.
Открытие, редактирование и сохранение XML
В этой главе будет показано как открывать, редактировать и сохранять XML файл, хранящийся на сервере.
Для этого мы будем использовать XSL, чтобы преобразовать XML документ в HTML форму. Значения XML элементов будут записываться в поля ввода в HTML форме. HTML форму можно будет редактировать. После редактирования данные можно будет отправить на сервер, и XML файл будет обновлен (мы покажем соответствующий код на PHP и ASP).
XML и XSL файлы
Для примера возьмем следующий XML документ ("tool.xml"):
<?xml version="1.0" encoding="UTF-8"?>
<tool>
<field id="prodName">
<value>HAMMER HG2606</value>
</field>
<field id="prodNo">
<value>32456240</value>
</field>
<field id="price">
<value>$30.00</value>
</field>
</tool>
И соответствующую таблицу стилей XSL ("tool.xsl"):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<form method="post" action="//msiter.ru/edittool.php">
<h2>Tool Information (edit):</h2>
<table border="0">
<xsl:for-each select="tool/field">
<tr>
<td><xsl:value-of select="@id"/></td>
<td>
<input type="text">
<xsl:attribute name="id">
<xsl:value-of select="@id" />
</xsl:attribute>
<xsl:attribute name="name">
<xsl:value-of select="@id" />
</xsl:attribute>
<xsl:attribute name="value">
<xsl:value-of select="value" />
</xsl:attribute>
</input>
</td>
</tr>
</xsl:for-each>
</table>
<br />
<input type="submit" id="btn_sub" name="btn_sub" value="Submit" />
<input type="reset" id="btn_res" name="btn_res" value="Reset" />
</form>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Код в приведенном выше XSL файле в цикле проходит по элементам XML файла и создает поле ввода для каждого XML элемента-"поля".
Значение атрибута "id" XML элемента-"поля" добавляется одновременно в атрибуты "id" и "name" каждого HTML поля ввода. Значение каждого XML элемента "value" добавляется в атрибут "value" каждого HTML поля ввода. В результате мы получаем редактируемую HTML форму, содержащую значения из XML файла.
Наконец, мы определяем вторую таблицу стилей XSL: "tool_updated.xsl". Этот XSL файл будет использоваться для отображения обновленных XML данных. Данная таблица стилей формирует не HTML форму, а статическую HTML таблицу:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>Updated Tool Information:</h2>
<table border="1">
<xsl:for-each select="tool/field">
<tr>
<td><xsl:value-of select="@id" /></td>
<td><xsl:value-of select="value" /></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
PHP файл
В файле "tool.xsl" указываем в атрибуте action формы файл "edittool.php".
Файл "edittool.php" содержит две функции: функция loadFile() загружает и преобразовывает XML файл для дальнейшего отображения, а функция updateFile() применяет сделанные изменения в XML файле:
<?php
function loadFile($xml, $xsl)
{
$xmlDoc = new DOMDocument();
$xmlDoc->load($xml);
$xslDoc = new DOMDocument();
$xslDoc->load($xsl);
$proc = new XSLTProcessor();
$proc->importStyleSheet($xslDoc);
echo $proc->transformToXML($xmlDoc);
}
function updateFile($xml)
{
$xmlLoad = simplexml_load_file($xml);
$postKeys = array_keys($_POST);
foreach($xmlLoad->children() as $x)
{
foreach($_POST as $key=>$value)
{
if($key == $x->attributes())
{
$x->value = $value;
}
}
}
$xmlLoad->asXML($xml);
loadFile($xml,"tool_updated.xsl");
}
if($_POST["btn_sub"] == "")
{
loadFile("tool.xml", "tool.xsl");
}
else
{
updateFile("tool.xml");
}
?>
Примечание: Все преобразования и изменения XML файла делаются на сервере. Это кросс-браузерное решение. Пользователь получит только HTML страницу, что будет работать в любом браузере.
ASP файл
В файле "tool.xsl" указываем в атрибуте action формы файл "edittool.asp".
Файл "edittool.asp" содержит две функции: функция loadFile() загружает и преобразовывает XML файл для дальнейшего отображения, а функция updateFile() применяет сделанные изменения в XML файле:
<%
function loadFile(xmlfile,xslfile)
Dim xmlDoc,xslDoc
'Загружаем XML и XSL файлы
set xmlDoc = Server.CreateObject("Microsoft.XMLDOM")
xmlDoc.async = false
xmlDoc.load(xmlfile)
set xslDoc = Server.CreateObject("Microsoft.XMLDOM")
xslDoc.async = false
xslDoc.load(xslfile)
'Преобразовываем файл
Response.Write(xmlDoc.transformNode(xslDoc))
end function
function updateFile(xmlfile)
Dim xmlDoc,rootEl,f
Dim i
'Загружаем XML файл
set xmlDoc = Server.CreateObject("Microsoft.XMLDOM")
xmlDoc.async = false
xmlDoc.load(xmlfile)
'Устанавливаем переменную rootEl равную корневому элементу
Set rootEl = xmlDoc.documentElement
'Цикл по набору формы
for i = 1 To Request.Form.Count
'Убираем элементы кнопок в форме
if instr(1,Request.Form.Key(i),"btn_")=0 then
'Метод selectSingleNode запрашивает XML файл на наличие одиночного узла,
'соответствующего запросу. Данный запрос ищет элемент value, который
'является потомком элемента field, у которого атрибут id соответствует
'текущему ключу в Form Collection. Когда соответствие будет найдено,
'установить свойство text равным значению текущего поля в Form Collection.
set f = rootEl.selectSingleNode("field[@id='" & _
Request.Form.Key(i) & "']/value")
f.Text = Request.Form(i)
end if
next
'Сохранить модифицированный XML файл
xmlDoc.save xmlfile
'Освобождаем все ссылки на объекты
set xmlDoc=nothing
set rootEl=nothing
set f=nothing
'Загружаем модифицированный XML файл с таблицей стилей,
'которая позволит пользователю увидеть отредактированную информацию
loadFile xmlfile,server.MapPath("tool_updated.xsl")
end function
'Если форма была отправлена, обновить XML файл и отобразить результат
'Если нет, преобразовать XML файл для редактирования
if Request.Form("btn_sub")="" then
loadFile server.MapPath("tool.xml"),server.MapPath("tool.xsl")
else
updateFile server.MapPath("tool.xml")
end if
%>