Как лучше делать XML данные для формирования страницы сайта?

maxim

Новичок
Как лучше делать XML данные для формирования страницы сайта?

У меня сейчас это делается так:

контроллер создает главный пустой документ, и кидает в него всякие общие данные: языковую версию(ru|en|...), данные о юзере и тд.
Затем вызвывает контроллер модуля, а он в свою очередь разные методы которые возвращают тоже дом документы
напрмер $article->getList($id_category) вернет
<?xml version="1.0"?>
<menu type="news">
<item ...>qqq</item>
<item ...>aaa</item>
<item ...>zzz</item>
</menu>
Затем контроллер модуля вставляет в главный домдокумент в нужное место
<menu type="news">
<item ...>qqq</item>
<item ...>aaa</item>
<item ...>zzz</item>
</menu>

А в итоге все это идет через XSLT юзеру.

Так вот вопрос кто как делает этот главный домдокумент с данными, и что возвращают методы классов
1) массивы или
2)(как у меня) домдокументы.

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

Спасибо.
 

Sherman

Mephi
Я в свое время делал так.

Есть класс бизнес логики, все методы какого-то класса слоя Data работают только с объектами подобных типов.

А сам класс бизнес логики имеет реализацию интерфейса IXMLable. Типа:

PHP:
interface IXMLable
{
   function getXML();
}
Таким образом, данные(Data) ничего не знают о представлении, они умеют общаться только со структурами данных.

А вот уже эти структуры данных умеют преобразовывть себя в тот формат, который нужен слою View(шаблоны, xslt и т.д.).

У меня они возвращали объект типа DomDocument.

А затем уже в конкртеном контроллере, все это дело собиралось в один большой xml, преобразовывалось с помощью xslt и отправлялось юзеру в HTML.

При таком подходе, если мне скажем не нужно XSLT(XML), то я прост меняю контроллер, но принципиально в слое Data ничего не придеться менять, т.к. струкутра объектов бизнес логики остается прежняя...
 

maxim

Новичок
Автор оригинала: Sherman

Есть класс бизнес логики, все методы какого-то класса слоя Data работают только с объектами подобных типов.

А сам класс бизнес логики имеет реализацию интерфейса IXMLable. Т

Таким образом, данные(Data) ничего не знают о представлении, они умеют общаться только со структурами данных.

А вот уже эти структуры данных умеют преобразовывть себя в тот формат, который нужен слою View(шаблоны, xslt и т.д.).

У меня они возвращали объект типа DomDocument.

А затем уже в конкртеном контроллере, все это дело собиралось в один большой xml, преобразовывалось с помощью xslt и отправлялось юзеру в HTML.
Спасибо за ответ. У Вас интересное решение.
Т.е. методы классов (например $article->getList($id_category)) у Вас тоже возвращают объект типа DomDocument. Можно ли чуть подробнее.

Я правльно понял, что в классе бизнес логики после того как Вы получили данные из базы хранятся в виде массива, а затем вызывается метод getXML который массив данных (array ) преобразовывает в XML?

И если можно поподробнее опишите слой Data. Что он делает, как данные из базы переходят в итоговый XML.


Может у кого то есть другие решения?
 

Sherman

Mephi
Не совсем так. Есть класс обертка для хранения любой структуры.

Пример:

Класс для хранения какого-либо объекта(например Статьи).

Код:
class ArticleStruct
	{		
		protected $obj = null;
		function __construct()
		{
			$this->obj = array(
			"id"=>0,						
			"title"=>"",		
			);
		}
		function __get($key)
		{
			if (isset($this->obj[$key]))
			{
				return $this->obj[$key];
			}
			return null;
		}
		function __set($key, $value)
		{
			if (isset($this->obj[$key]))
			{
				$this->obj[$key] = $value;
			}			
		}
	}
// слой данных(Data)
// данный класс умеет работать(например сохранять и получать данные из бд) только с объектами типа ArticleStruct

Код:
class BaseArticle
	{
		private $data = null;
		public $dataCollection = null;
		function __construct()
		{
			$this->data = new ArticleStruct();
			$this->dataCollection = new BaseCollection(); // класс коллекция для хранения объектов
		}
		public function getArticleById($articleId)
		{
			//1. get article by Id
			//2. fill articlestruct obj 	
			return 	$this->data;
		}
	}
Теперь предположим, что мы хотим добавить поддержку XML для того, чтобы можно было применять XSLT для вывода статей.

Объявлем интерфейс IXMLable:
Код:
interface IXMLAble
	{
		public function getXML(); //get obj as xml document
	}
Наши статьи должны уметь сохранять себя в XML:
Код:
class ArticleStruct [b]implements IXMLable[/b] 
	{		
		protected $obj = null;
		function __construct()
		{
			$this->obj = array(
			"id"=>0,						
			"title"=>"",		
			);
		}
		function __get($key)
		{
			if (isset($this->obj[$key]))
			{
				return $this->obj[$key];
			}
			return null;
		}
		function __set($key, $value)
		{
			if (isset($this->obj[$key]))
			{
				$this->obj[$key] = $value;
			}			
		}
		[b]public function getXML()[/b]
		{
			//пример сериализации объекта в xml
			$domObj = new DOMDocument("1.0", "UTF-8");
			//add root
			$rootNode = $domObj->createElement("obj");
			$domObj->appendChild($rootNode);
			
			$classNameNode = $domObj->createAttribute("className");
			$classNameNodeValue = $domObj->createTextNode(iconv("WINDOWS-1251", "UTF-8",  get_class($this)));	
			$classNameNode->appendChild($classNameNodeValue);
			$rootNode->appendChild($classNameNode);
			foreach($this->obj as $key => $value)
			{
				$itemNode = $domObj->createElement($key, $value);
				$rootNode->appendChild($itemNode);				
			}
			return $domObj;
		}
Далее в контроллере мы создаем экземпляр класса BaseArticle и получаем структуру, затем из нее получаем xml и кидаем его в общий поток(большой xml) к которому потом применяем таблицу стилей(XSL).

Система является довольно гибкой.

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

В моем лучае изначально не было поддержки XML, она добавилась позже.

Вобщем вариантов масса.
 

maxim

Новичок
Интересный подход, только сложноват - зато универсален. Разбираюсь.
 

voituk

прозревший
Sherman
А можно как-то на реализацию взгянуть на рабочем примере?
Желательно максимально простом, но демонстрирующем максимум гибкости.
 
Сверху