Свернутый текст
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 и переопределение массивов дабы избежать остатки хмл в кеше пхп, но это тоже не решило проблему.
И причем самое интересное что первый раз проходит нормально. Второй, третий и последующие разы происходит удвоение и я не знаю почему так.
Где косяк...
Но проблема осталась и как мне кажется она кроется где-то в выводе.
История получается такая:
в хмл есть 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 файла или создания нового корня.
Хотя кашу маслом не испортишь пойду пробую переписать.
Конечно же это не очень эффективно и не совсем правильно и если заработает appendxml то можно будет фрагмент получения из массива вынести в отдельный метод, или поставить какой-то флаг на получение xml файла или создания нового корня.
Хотя кашу маслом не испортишь пойду пробую переписать.
Спустя 1 час, 51 минута, 8 секунд (15.03.2011 - 18:30) maximvg написал(а):
функцию переписал и теперь вместо create & append появилась функция makexml
Класс целиком (если нужен кому конечно):
В конфиге написал
в ашттаккесс
Понимаю что продублировал, но сейчас это не важно.
Как оказалось из написания дальнейших функций такая трабла встречается только в chrome. В то время когда опера и фф все делают как надо - один раз, chrome все делает по три раза - три раза запускает функцию добавления в БД, три раза запускает makexml.
Может быть что-то еще он тоже делает три раза, похоже что chrome сделали для тормозов (кто с первого раза не понимает).
require-, include_once тоже не помогает.
Есть варианты как научить chrome все делать один раз?
UPD: safari ведет себя также как и chrome по три раза обращаясь к документу. Я думаю что это все из-за оптимизации времени загрузки страницы где создается несколько потоков одновременно которые одновременно обращаются к странице потом разделяя между собой результат.
Других мыслей у меня нет.
Выход из ситуации вижу в переносе фрагмента скрипта с php на JavaScript - должно помочь :)
Свернутый текст
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 файлов тогда текст будет выглядеть так:
В то время как организовав открытие файла в методе apendxml можно организовать так:
Тем более что при
хром и сафари все равно обращается три раза и добавление проводит три раза.
$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);
хром и сафари все равно обращается три раза и добавление проводит три раза.