[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: добавление элементов в корень xml
maximvg
Есть функция appendxml
Свернутый текст

public function appendxml($node, $element, $nodeBOTH, $filename, $cdata = false, $idprefix){
if (!isset($node) || !isset($nodeBOTH) || !isset($filename)) return false;
if (!is_file($filename)) return false;

$this->DOMxml->load($filename);

/// echo count($nodeBOTH);
for ($i=0; $i<count($nodeBOTH); $i++){
if (isset($b)) unset($b);
$b = $this->DOMxml->createElement("$element");
$b->setAttribute("id", $nodeBOTH[$i][$idprefix]);
foreach ($nodeBOTH[$i] as $key=>$value){
$expression = $this->DOMxml->createElement("$key");
if (!$cdata)
$expression->appendChild(
$this->DOMxml->createTextNode("$value")
);

else
$expression->appendChild(
$this->DOMxml->createCDATASection("$value")
);

$b->appendChild($expression);
}
if (isset($root)) unset($root);
$root = $this->DOMxml->getElementsByTagName($node)->item(0);
$root->appendChild($b);
}

if ($this->savexml($filename, $this->DOMxml)) return $this->DOMxml;
else return false;

echo $this->DOMxml->saveXml()."<br>";
}

private function savexml($filename, $obj){
if (!isset($filename)) return false;

$obj->save($filename);
return true;
}


которая работает не так, как мне хотелось и мне хочется это неподобство исправить.

Входные параметры:
$nodeBOTH - массив формата [число][имя]

Главная проблема в том, что $this->DOMxml->saveXml() выдает увеличенное в 2 раза количество элементов и добавляет к исходному количеству т.е. если изначально Xml 3 элемента, то после добавления еще 3х элементов будет 3 + 6 элементов.

Не могу понять почему так происходит и как это побороть.

Хелп плиз



Спустя 11 часов, 26 минут, 54 секунды (15.03.2011 - 10:55) linker написал(а):
Это
if (isset($root)) unset($root);
$root = $this->DOMxml->getElementsByTagName($node)->item(0);
$root->appendChild($b);
заменяется на это
$this->DOMxml->documentElement->appendChild($b);
но это если вы действительно хотите добавлять элементы в корень, как написано в заголовке темы.

Спустя 1 час, 11 минут, 50 секунд (15.03.2011 - 12:06) maximvg написал(а):
Поменять это на это - хорошее решение и я поменял.

Но проблема осталась и как мне кажется она кроется где-то в выводе.

История получается такая:
в хмл есть n записей - это записи умножаются на 2 и к ним добавляются те, которые надо добавить.

Везде где можно поставил unset и переопределение массивов дабы избежать остатки хмл в кеше пхп, но это тоже не решило проблему.

И причем самое интересное что первый раз проходит нормально. Второй, третий и последующие разы происходит удвоение и я не знаю почему так.

Где косяк...

Спустя 37 минут, 36 секунд (15.03.2011 - 12:44) linker написал(а):
Возможно ибо ничего иного я не вижу:
$this->DOMxml = new DomDocument();
$this->DOMxml->load($filename);

Спустя 49 минут, 49 секунд (15.03.2011 - 13:34) maximvg написал(а):
Весь класс:
Свернутый текст
<?
final class
xml extends loadfile{

var $DOMxml = NULL;


function __construct(){
$this->DOMxml = new DOMDocument();

$this->DOMxml->preserveWhiteSpace = false;
$this->DOMxml->formatOutput = true;

parent::__construct();
}

function __destructor(){
unset($this);
}

public function create($node, $element, $mysqlBOTH, $filename, $cdata = false, $idprefix){
if (!isset($node) || !isset($mysqlBOTH) || !isset($filename)) return false;
if (is_file($filename)) $this->destroy($filename);

if (isset($this->DOMxml)) unset($this->DOMxml);
$this->DOMxml = new DOMDocument();

$this->DOMxml->preserveWhiteSpace = false;
$this->DOMxml->formatOutput = true;

$r = $this->DOMxml->createElement("$node");
$this->DOMxml->appendChild($r);
for ($i=0; $i<count($mysqlBOTH); $i++){
$b = $this->DOMxml->createElement("$element");
$b->setAttribute("id", $mysqlBOTH[$i][$idprefix]);
foreach ($mysqlBOTH[$i] as $key=>$value){
$expression = $this->DOMxml->createElement("$key");
if (!$cdata)
$expression->appendChild(
$this->DOMxml->createTextNode("$value")
);

else
$expression->appendChild(
$this->DOMxml->createCDATASection("$value")
);

$b->appendChild($expression);
}
$r->appendChild($b);
}

// $xml = $this->DOMxml->saveXML();
if ($this->savexml($filename, $this->DOMxml)) return $this->DOMxml;
else return false;
}

public function appendxml($node, $element, $nodeBOTH, $filename, $cdata = false, $idprefix){
if (!isset($node) || !isset($nodeBOTH) || !isset($filename)) return false;
if (!is_file($filename)) return false;

$this->DOMxml->load($filename);

/// echo count($nodeBOTH);
for ($i=0; $i<count($nodeBOTH); $i++){
if (isset($b)) unset($b);
$b = $this->DOMxml->createElement("$element");
$b->setAttribute("id", $nodeBOTH[$i][$idprefix]);
foreach ($nodeBOTH[$i] as $key=>$value){
$expression = $this->DOMxml->createElement("$key");
if (!$cdata)
$expression->appendChild(
$this->DOMxml->createTextNode("$value")
);

else
$expression->appendChild(
$this->DOMxml->createCDATASection("$value")
);

$b->appendChild($expression);
}
$this->DOMxml->documentElement->appendChild($b);
}

if ($this->savexml($filename, $this->DOMxml)) return $this->DOMxml;
else return false;

echo $this->DOMxml->saveXml()."<br>";
}

private function savexml($filename, $obj){
if (!isset($filename)) return false;
echo $obj->saveXML();
$obj->save($filename);
return true;
}

private function destroy($filename){
if ($this->removefile($filename)) return $filename;
else return false;
}

public function XHTMLtransform($xml, $href){
// Loading XSLT site
$stylesheet = new DOMDocument;
$stylesheet->substituteEntities = true;
if ($stylesheet->load($href) == false)
die('Failed to load XSLT file');

// XSLT transformation
$xsl = new XSLTProcessor();
$xsl->importStyleSheet($stylesheet);
$output = $xsl->transformToXML($xml); // transforming
if (!empty($output)) return $output;
else return false;
}

public function view($xml){
if (!empty($xml)) echo $xml;
else return false;
return true;
}
}

?>

Спустя 2 часа, 36 минут, 37 секунд (15.03.2011 - 16:10) linker написал(а):
Забавная вещь, метод create видимо слово в слово повторяет метод appendxml. Может тут собака порылась?

Спустя 28 минут, 35 секунд (15.03.2011 - 16:39) maximvg написал(а):
метод create отличается от appendxml тем, что create создает корневой элемент и к нему добавляет все из массива $mysqlBOTH, а appendxml получает xml из файла и добавляет к нему данные полученные из массива $nodeBOTH.

Конечно же это не очень эффективно и не совсем правильно и если заработает appendxml то можно будет фрагмент получения из массива вынести в отдельный метод, или поставить какой-то флаг на получение xml файла или создания нового корня.

Хотя кашу маслом не испортишь пойду пробую переписать.

Спустя 1 час, 51 минута, 8 секунд (15.03.2011 - 18:30) maximvg написал(а):
функцию переписал и теперь вместо create & append появилась функция makexml

Свернутый текст
		 public function makexml($node, $element, $nodeBOTH, $filename, $cdata = false, $idprefix = '', $create = false){
if (!isset($node) || !isset($nodeBOTH) || !isset($filename)) return false;
if (!is_file($filename)) return false;

if ($create){
$nodes = $this->DOMxml->createElement("$node");
$this->DOMxml->appendChild($nodes);
} else {
$this->DOMxml->load($filename);
$nodes = $this->DOMxml->documentElement;
}

$i=0;

foreach ($nodeBOTH as $nodeboth){
if (isset($b)) unset($b);

$b = $this->DOMxml->createElement("$element");
if (isset($nodeBOTH[$i][$idprefix])) $b->setAttribute("id", $nodeBOTH[$i][$idprefix]);

foreach ($nodeboth as $key=>$value){
$expression = $this->DOMxml->createElement("$key");
if (!$cdata)
$expression->appendChild(
$this->DOMxml->createTextNode("$value")
);

else
$expression->appendChild(
$this->DOMxml->createCDATASection("$value")
);

$b->appendChild($expression);
}
$nodes->appendChild($b);
$i++;
}

if ($this->savexml($filename, $this->DOMxml)) return $this->DOMxml;
else return false;
}


Класс целиком (если нужен кому конечно):

Свернутый текст
<?
class
xml extends db{

var $DOMxml = NULL;

function __construct($type = 'mycms'){
if (isset($this->DOMxml)) unset($this->DOMxml);
$this->DOMxml = new DOMDocument();

$this->DOMxml->preserveWhiteSpace = false;
$this->DOMxml->formatOutput = true;

parent::__construct($type);
}

function __destructor(){
unset($this);
}

public function makexml($node, $element, $nodeBOTH, $filename, $cdata = false, $idprefix = '', $create = false){
if (!isset($node) || !isset($nodeBOTH) || !isset($filename)) return false;
if (!is_file($filename)) return false;

if ($create){
$nodes = $this->DOMxml->createElement("$node");
$this->DOMxml->appendChild($nodes);
} else {
$this->DOMxml->load($filename);
$nodes = $this->DOMxml->documentElement;
}

$i=0;

foreach ($nodeBOTH as $nodeboth){
if (isset($b)) unset($b);

$b = $this->DOMxml->createElement("$element");
if (isset($nodeBOTH[$i][$idprefix])) $b->setAttribute("id", $nodeBOTH[$i][$idprefix]);

foreach ($nodeboth as $key=>$value){
$expression = $this->DOMxml->createElement("$key");
if (!$cdata)
$expression->appendChild(
$this->DOMxml->createTextNode("$value")
);

else
$expression->appendChild(
$this->DOMxml->createCDATASection("$value")
);

$b->appendChild($expression);
}
$nodes->appendChild($b);
$i++;
}

if ($this->savexml($filename, $this->DOMxml)) return $this->DOMxml;
else return false;
}

private function savexml($filename, $obj){
if (!isset($filename)) return false;
if (is_file($filename)) $this->destroyxml($filename);

$obj->save($filename);

return true;
}

private function destroyxml($filename){
$loadfile = new loadfile();
if ($loadfile->removefile($filename)) return $filename;
else return false;
}

public function XHTMLtransform($xml, $href){
// Loading XSLT site
$stylesheet = new DOMDocument;
$stylesheet->substituteEntities = true;
if ($stylesheet->load($href) == false)
die('Failed to load XSLT file');

// XSLT transformation
$xsl = new XSLTProcessor();
$xsl->importStyleSheet($stylesheet);
$output = $xsl->transformToXML($xml); // transforming
if (!empty($output)) return $output;
else return false;
}

public function viewxml($xml){
if (!empty($xml)) print($xml);
else return false;
return true;
}
}

?>


В конфиге написал
ini_set("register_globals","off");

в ашттаккесс
php_flag register_globals off


Понимаю что продублировал, но сейчас это не важно.

Как оказалось из написания дальнейших функций такая трабла встречается только в chrome. В то время когда опера и фф все делают как надо - один раз, chrome все делает по три раза - три раза запускает функцию добавления в БД, три раза запускает makexml.

Может быть что-то еще он тоже делает три раза, похоже что chrome сделали для тормозов (кто с первого раза не понимает).

require-, include_once тоже не помогает.

Есть варианты как научить chrome все делать один раз?

UPD: safari ведет себя также как и chrome по три раза обращаясь к документу. Я думаю что это все из-за оптимизации времени загрузки страницы где создается несколько потоков одновременно которые одновременно обращаются к странице потом разделяя между собой результат.
Других мыслей у меня нет.

Выход из ситуации вижу в переносе фрагмента скрипта с php на JavaScript - должно помочь :)

Спустя 15 часов, 32 минуты, 26 секунд (16.03.2011 - 10:03) linker написал(а):
Я это всё к тому, что в appendxml нет необходимости подгружать xml-файл, т.е. вот это
$this->DOMxml->load($filename);
нужно от туда выкинуть. Элемент-корень xml-файла ничем не отличается от какого-либо иного элемента. Поэтому к нему спокойно можно применять и appendxml().
class xmlfile
{
protected _doc = null;
protected _path = '';

public function __construct($location)
{
$this->_path = $location;
$this->open();
}

public function __destruct()
{
$this->savexml();
}

public function open()
{
$this->_doc = new DomDocument();
if (file_exists($this->_path))
$this->_doc->load($this->_path);
}

public function appendxml()
{
...
}

public function savexml()
{
}

...
}

$xml = new xmlfile('./file.xml');
$xml->appendxml();
unset($xml);

Спустя 4 дня, 5 часов, 34 минуты, 48 секунд (20.03.2011 - 15:37) maximvg написал(а):
Если на моей странице будет несколько блоков формируемых из xml файлов тогда текст будет выглядеть так:

$xml = new xmlfile('./file.xml');
$xml->appendxml();
unset($xml);

$xml = new xmlfile('./file2.xml');
$xml->appendxml();
unset($xml);


В то время как организовав открытие файла в методе apendxml можно организовать так:


$xml = new xmlfile();
$xml->appendxml('./file.xml');
$xml->appendxml('./file2.xml');
......



Тем более что при
$xml = new xmlfile('./file.xml');
$xml->appendxml();
unset($xml);


хром и сафари все равно обращается три раза и добавление проводит три раза.

Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2025 Invision Power Services, Inc.