Version compatible with Piwik 2.1
[piwik-CASLogin.git] / CAS / CAS / domxml-php4-to-php5.php
1 <?php
2 /*
3         Requires PHP5, uses built-in DOM extension.
4         To be used in PHP4 scripts using DOMXML extension: allows PHP4/DOMXML scripts to run on PHP5/DOM.
5         (Optional: requires PHP5/XSL extension for domxml_xslt functions, PHP>=5.1 for XPath evaluation functions, and PHP>=5.1/libxml for DOMXML error reports)
6
7         Typical use:
8         {
9                 if (PHP_VERSION>='5')
10                         require_once('domxml-php4-to-php5.php');
11         }
12
13         Version 1.21.1a, 2009-03-13, http://alexandre.alapetite.fr/doc-alex/domxml-php4-php5/
14
15         ------------------------------------------------------------------
16         Written by Alexandre Alapetite, http://alexandre.alapetite.fr/cv/
17
18         Copyright 2004-2009, GNU Lesser General Public License,
19         http://www.gnu.org/licenses/lgpl.html
20
21         This program is free software: you can redistribute it and/or modify
22         it under the terms of the GNU Lesser General Public License as published by
23         the Free Software Foundation, either version 3 of the License, or
24         (at your option) any later version.
25         This program is distributed in the hope that it will be useful,
26         but WITHOUT ANY WARRANTY; without even the implied warranty of
27         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28         GNU Lesser General Public License for more details.
29         You should have received a copy of the GNU Lesser General Public License
30         along with this program. If not, see <http://www.gnu.org/licenses/lgpl.html>
31
32         == Rights and obligations ==
33         - Attribution: You must give the original author credit.
34         - Share Alike: If you alter or transform this library,
35            you may distribute the resulting library only under the same license GNU/LGPL.
36         - In case of jurisdiction dispute, the French law is authoritative.
37         - Any of these conditions can be waived if you get permission from Alexandre Alapetite.
38         - Not required, but please send to Alexandre Alapetite the modifications you make,
39            in order to improve this file for the benefit of everybody.
40
41         If you want to distribute this code, please do it as a link to:
42         http://alexandre.alapetite.fr/doc-alex/domxml-php4-php5/
43 */
44
45 define('DOMXML_LOAD_PARSING',0);
46 define('DOMXML_LOAD_VALIDATING',1);
47 define('DOMXML_LOAD_RECOVERING',2);
48 define('DOMXML_LOAD_SUBSTITUTE_ENTITIES',4);
49 //define('DOMXML_LOAD_COMPLETE_ATTRS',8);
50 define('DOMXML_LOAD_DONT_KEEP_BLANKS',16);
51
52 function domxml_new_doc($version) {return new php4DOMDocument();}
53 function domxml_new_xmldoc($version) {return new php4DOMDocument();}
54 function domxml_open_file($filename,$mode=DOMXML_LOAD_PARSING,&$error=null)
55 {
56         $dom=new php4DOMDocument($mode);
57         $errorMode=(func_num_args()>2)&&defined('LIBXML_VERSION');
58         if ($errorMode) libxml_use_internal_errors(true);
59         if (!$dom->myDOMNode->load($filename)) $dom=null;
60         if ($errorMode)
61         {
62                 $error=array_map('_error_report',libxml_get_errors());
63                 libxml_clear_errors();
64         }
65         return $dom;
66 }
67 function domxml_open_mem($str,$mode=DOMXML_LOAD_PARSING,&$error=null)
68 {
69         $dom=new php4DOMDocument($mode);
70         $errorMode=(func_num_args()>2)&&defined('LIBXML_VERSION');
71         if ($errorMode) libxml_use_internal_errors(true);
72         if (!$dom->myDOMNode->loadXML($str)) $dom=null;
73         if ($errorMode)
74         {
75                 $error=array_map('_error_report',libxml_get_errors());
76                 libxml_clear_errors();
77         }
78         return $dom;
79 }
80 function html_doc($html_doc,$from_file=false)
81 {
82         $dom=new php4DOMDocument();
83         if ($from_file) $result=$dom->myDOMNode->loadHTMLFile($html_doc);
84         else $result=$dom->myDOMNode->loadHTML($html_doc);
85         return $result ? $dom : null;
86 }
87 function html_doc_file($filename) {return html_doc($filename,true);}
88 function xmldoc($str) {return domxml_open_mem($str);}
89 function xmldocfile($filename) {return domxml_open_file($filename);}
90 function xpath_eval($xpath_context,$eval_str,$contextnode=null) {return $xpath_context->xpath_eval($eval_str,$contextnode);}
91 function xpath_new_context($dom_document) {return new php4DOMXPath($dom_document);}
92 function xpath_register_ns($xpath_context,$prefix,$namespaceURI) {return $xpath_context->myDOMXPath->registerNamespace($prefix,$namespaceURI);}
93 function _entityDecode($text) {return html_entity_decode(strtr($text,array('&apos;'=>'\'')),ENT_QUOTES,'UTF-8');}
94 function _error_report($error) {return array('errormessage'=>$error->message,'nodename'=>'','line'=>$error->line,'col'=>$error->column)+($error->file==''?array():array('directory'=>dirname($error->file),'file'=>basename($error->file)));}
95
96 class php4DOMAttr extends php4DOMNode
97 {
98         function __get($name)
99         {
100                 if ($name==='name') return $this->myDOMNode->name;
101                 else return parent::__get($name);
102         }
103         function name() {return $this->myDOMNode->name;}
104         function set_content($text) {}
105         //function set_value($content) {return $this->myDOMNode->value=htmlspecialchars($content,ENT_QUOTES);}
106         function specified() {return $this->myDOMNode->specified;}
107         function value() {return $this->myDOMNode->value;}
108 }
109
110 class php4DOMDocument extends php4DOMNode
111 {
112         function php4DOMDocument($mode=DOMXML_LOAD_PARSING)
113         {
114                 $this->myDOMNode=new DOMDocument();
115                 $this->myOwnerDocument=$this;
116                 if ($mode & DOMXML_LOAD_VALIDATING) $this->myDOMNode->validateOnParse=true;
117                 if ($mode & DOMXML_LOAD_RECOVERING) $this->myDOMNode->recover=true;
118                 if ($mode & DOMXML_LOAD_SUBSTITUTE_ENTITIES) $this->myDOMNode->substituteEntities=true;
119                 if ($mode & DOMXML_LOAD_DONT_KEEP_BLANKS) $this->myDOMNode->preserveWhiteSpace=false;
120         }
121         function add_root($name)
122         {
123                 if ($this->myDOMNode->hasChildNodes()) $this->myDOMNode->removeChild($this->myDOMNode->firstChild);
124                 return new php4DOMElement($this->myDOMNode->appendChild($this->myDOMNode->createElement($name)),$this->myOwnerDocument);
125         }
126         function create_attribute($name,$value)
127         {
128                 $myAttr=$this->myDOMNode->createAttribute($name);
129                 $myAttr->value=htmlspecialchars($value,ENT_QUOTES);
130                 return new php4DOMAttr($myAttr,$this);
131         }
132         function create_cdata_section($content) {return new php4DOMNode($this->myDOMNode->createCDATASection($content),$this);}
133         function create_comment($data) {return new php4DOMNode($this->myDOMNode->createComment($data),$this);}
134         function create_element($name) {return new php4DOMElement($this->myDOMNode->createElement($name),$this);}
135         function create_element_ns($uri,$name,$prefix=null)
136         {
137                 if ($prefix==null) $prefix=$this->myDOMNode->lookupPrefix($uri);
138                 if (($prefix==null)&&(($this->myDOMNode->documentElement==null)||(!$this->myDOMNode->documentElement->isDefaultNamespace($uri)))) $prefix='a'.sprintf('%u',crc32($uri));
139                 return new php4DOMElement($this->myDOMNode->createElementNS($uri,$prefix==null ? $name : $prefix.':'.$name),$this);
140         }
141         function create_entity_reference($content) {return new php4DOMNode($this->myDOMNode->createEntityReference($content),$this);} //By Walter Ebert 2007-01-22
142         function create_processing_instruction($target,$data=''){return new php4DomProcessingInstruction($this->myDOMNode->createProcessingInstruction($target,$data),$this);}
143         function create_text_node($content) {return new php4DOMText($this->myDOMNode->createTextNode($content),$this);}
144         function document_element() {return parent::_newDOMElement($this->myDOMNode->documentElement,$this);}
145         function dump_file($filename,$compressionmode=false,$format=false)
146         {
147                 $format0=$this->myDOMNode->formatOutput;
148                 $this->myDOMNode->formatOutput=$format;
149                 $res=$this->myDOMNode->save($filename);
150                 $this->myDOMNode->formatOutput=$format0;
151                 return $res;
152         }
153         function dump_mem($format=false,$encoding=false)
154         {
155                 $format0=$this->myDOMNode->formatOutput;
156                 $this->myDOMNode->formatOutput=$format;
157                 $encoding0=$this->myDOMNode->encoding;
158                 if ($encoding) $this->myDOMNode->encoding=$encoding;
159                 $dump=$this->myDOMNode->saveXML();
160                 $this->myDOMNode->formatOutput=$format0;
161                 if ($encoding) $this->myDOMNode->encoding= $encoding0=='' ? 'UTF-8' : $encoding0; //UTF-8 is XML default encoding
162                 return $dump;
163         }
164         function free()
165         {
166                 if ($this->myDOMNode->hasChildNodes()) $this->myDOMNode->removeChild($this->myDOMNode->firstChild);
167                 $this->myDOMNode=null;
168                 $this->myOwnerDocument=null;
169         }
170         function get_element_by_id($id) {return parent::_newDOMElement($this->myDOMNode->getElementById($id),$this);}
171         function get_elements_by_tagname($name)
172         {
173                 $myDOMNodeList=$this->myDOMNode->getElementsByTagName($name);
174                 $nodeSet=array();
175                 $i=0;
176                 if (isset($myDOMNodeList))
177                         while ($node=$myDOMNodeList->item($i++)) $nodeSet[]=new php4DOMElement($node,$this);
178                 return $nodeSet;
179         }
180         function html_dump_mem() {return $this->myDOMNode->saveHTML();}
181         function root() {return parent::_newDOMElement($this->myDOMNode->documentElement,$this);}
182         function xinclude() {return $this->myDOMNode->xinclude();}
183         function xpath_new_context() {return new php4DOMXPath($this);}
184 }
185
186 class php4DOMElement extends php4DOMNode
187 {
188         function add_namespace($uri,$prefix)
189         {
190                 if ($this->myDOMNode->hasAttributeNS('http://www.w3.org/2000/xmlns/',$prefix)) return false;
191                 else
192                 {
193                         $this->myDOMNode->setAttributeNS('http://www.w3.org/2000/xmlns/','xmlns:'.$prefix,$uri); //By Daniel Walker 2006-09-08
194                         return true;
195                 }
196         }
197         function get_attribute($name) {return $this->myDOMNode->getAttribute($name);}
198         function get_attribute_node($name) {return parent::_newDOMElement($this->myDOMNode->getAttributeNode($name),$this->myOwnerDocument);}
199         function get_elements_by_tagname($name)
200         {
201                 $myDOMNodeList=$this->myDOMNode->getElementsByTagName($name);
202                 $nodeSet=array();
203                 $i=0;
204                 if (isset($myDOMNodeList))
205                         while ($node=$myDOMNodeList->item($i++)) $nodeSet[]=new php4DOMElement($node,$this->myOwnerDocument);
206                 return $nodeSet;
207         }
208         function has_attribute($name) {return $this->myDOMNode->hasAttribute($name);}
209         function remove_attribute($name) {return $this->myDOMNode->removeAttribute($name);}
210         function set_attribute($name,$value)
211         {
212                 //return $this->myDOMNode->setAttribute($name,$value); //Does not return a DomAttr
213                 $myAttr=$this->myDOMNode->ownerDocument->createAttribute($name);
214                 $myAttr->value=htmlspecialchars($value,ENT_QUOTES); //Entity problem reported by AL-DesignWorks 2007-09-07
215                 $this->myDOMNode->setAttributeNode($myAttr);
216                 return new php4DOMAttr($myAttr,$this->myOwnerDocument);
217         }
218         /*function set_attribute_node($attr)
219         {
220                 $this->myDOMNode->setAttributeNode($this->_importNode($attr));
221                 return $attr;
222         }*/
223         function set_name($name)
224         {
225                 if ($this->myDOMNode->prefix=='') $newNode=$this->myDOMNode->ownerDocument->createElement($name);
226                 else $newNode=$this->myDOMNode->ownerDocument->createElementNS($this->myDOMNode->namespaceURI,$this->myDOMNode->prefix.':'.$name);
227                 $myDOMNodeList=$this->myDOMNode->attributes;
228                 $i=0;
229                 if (isset($myDOMNodeList))
230                         while ($node=$myDOMNodeList->item($i++))
231                                 if ($node->namespaceURI=='') $newNode->setAttribute($node->name,$node->value);
232                                 else $newNode->setAttributeNS($node->namespaceURI,$node->nodeName,$node->value);
233                 $myDOMNodeList=$this->myDOMNode->childNodes;
234                 if (isset($myDOMNodeList))
235                         while ($node=$myDOMNodeList->item(0)) $newNode->appendChild($node);
236                 $this->myDOMNode->parentNode->replaceChild($newNode,$this->myDOMNode);
237                 $this->myDOMNode=$newNode;
238                 return true;
239         }
240         function tagname() {return $this->tagname;}
241 }
242
243 class php4DOMNode
244 {
245         public $myDOMNode;
246         public $myOwnerDocument;
247         function php4DOMNode($aDomNode,$aOwnerDocument)
248         {
249                 $this->myDOMNode=$aDomNode;
250                 $this->myOwnerDocument=$aOwnerDocument;
251         }
252         function __get($name)
253         {
254                 switch ($name)
255                 {
256                         case 'type': return $this->myDOMNode->nodeType;
257                         case 'tagname': return ($this->myDOMNode->nodeType===XML_ELEMENT_NODE) ? $this->myDOMNode->localName : $this->myDOMNode->tagName; //Avoid namespace prefix for DOMElement
258                         case 'content': return $this->myDOMNode->textContent;
259                         case 'value': return $this->myDOMNode->value;
260                         default:
261                                 $myErrors=debug_backtrace();
262                                 trigger_error('Undefined property: '.get_class($this).'::$'.$name.' ['.$myErrors[0]['file'].':'.$myErrors[0]['line'].']',E_USER_NOTICE);
263                                 return false;
264                 }
265         }
266         function add_child($newnode) {return $this->append_child($newnode);}
267         function add_namespace($uri,$prefix) {return false;}
268         function append_child($newnode) {return self::_newDOMElement($this->myDOMNode->appendChild($this->_importNode($newnode)),$this->myOwnerDocument);}
269         function append_sibling($newnode) {return self::_newDOMElement($this->myDOMNode->parentNode->appendChild($this->_importNode($newnode)),$this->myOwnerDocument);}
270         function attributes()
271         {
272                 $myDOMNodeList=$this->myDOMNode->attributes;
273                 if (!(isset($myDOMNodeList)&&$this->myDOMNode->hasAttributes())) return null;
274                 $nodeSet=array();
275                 $i=0;
276                 while ($node=$myDOMNodeList->item($i++)) $nodeSet[]=new php4DOMAttr($node,$this->myOwnerDocument);
277                 return $nodeSet;
278         }
279         function child_nodes()
280         {
281                 $myDOMNodeList=$this->myDOMNode->childNodes;
282                 $nodeSet=array();
283                 $i=0;
284                 if (isset($myDOMNodeList))
285                         while ($node=$myDOMNodeList->item($i++)) $nodeSet[]=self::_newDOMElement($node,$this->myOwnerDocument);
286                 return $nodeSet;
287         }
288         function children() {return $this->child_nodes();}
289         function clone_node($deep=false) {return self::_newDOMElement($this->myDOMNode->cloneNode($deep),$this->myOwnerDocument);}
290         //dump_node($node) should only be called on php4DOMDocument
291         function dump_node($node=null) {return $node==null ? $this->myOwnerDocument->myDOMNode->saveXML($this->myDOMNode) : $this->myOwnerDocument->myDOMNode->saveXML($node->myDOMNode);}
292         function first_child() {return self::_newDOMElement($this->myDOMNode->firstChild,$this->myOwnerDocument);}
293         function get_content() {return $this->myDOMNode->textContent;}
294         function has_attributes() {return $this->myDOMNode->hasAttributes();}
295         function has_child_nodes() {return $this->myDOMNode->hasChildNodes();}
296         function insert_before($newnode,$refnode) {return self::_newDOMElement($this->myDOMNode->insertBefore($this->_importNode($newnode),$refnode==null?null:$refnode->myDOMNode),$this->myOwnerDocument);}
297         function is_blank_node() {return ($this->myDOMNode->nodeType===XML_TEXT_NODE)&&preg_match('%^\s*$%',$this->myDOMNode->nodeValue);}
298         function last_child() {return self::_newDOMElement($this->myDOMNode->lastChild,$this->myOwnerDocument);}
299         function new_child($name,$content)
300         {
301                 $mySubNode=$this->myDOMNode->ownerDocument->createElement($name);
302                 $mySubNode->appendChild($this->myDOMNode->ownerDocument->createTextNode(_entityDecode($content)));
303                 $this->myDOMNode->appendChild($mySubNode);
304                 return new php4DOMElement($mySubNode,$this->myOwnerDocument);
305         }
306         function next_sibling() {return self::_newDOMElement($this->myDOMNode->nextSibling,$this->myOwnerDocument);}
307         function node_name() {return ($this->myDOMNode->nodeType===XML_ELEMENT_NODE) ? $this->myDOMNode->localName : $this->myDOMNode->nodeName;} //Avoid namespace prefix for DOMElement
308         function node_type() {return $this->myDOMNode->nodeType;}
309         function node_value() {return $this->myDOMNode->nodeValue;}
310         function owner_document() {return $this->myOwnerDocument;}
311         function parent_node() {return self::_newDOMElement($this->myDOMNode->parentNode,$this->myOwnerDocument);}
312         function prefix() {return $this->myDOMNode->prefix;}
313         function previous_sibling() {return self::_newDOMElement($this->myDOMNode->previousSibling,$this->myOwnerDocument);}
314         function remove_child($oldchild) {return self::_newDOMElement($this->myDOMNode->removeChild($oldchild->myDOMNode),$this->myOwnerDocument);}
315         function replace_child($newnode,$oldnode) {return self::_newDOMElement($this->myDOMNode->replaceChild($this->_importNode($newnode),$oldnode->myDOMNode),$this->myOwnerDocument);}
316         function replace_node($newnode) {return self::_newDOMElement($this->myDOMNode->parentNode->replaceChild($this->_importNode($newnode),$this->myDOMNode),$this->myOwnerDocument);}
317         function set_content($text) {return $this->myDOMNode->appendChild($this->myDOMNode->ownerDocument->createTextNode(_entityDecode($text)));} //Entity problem reported by AL-DesignWorks 2007-09-07
318         //function set_name($name) {return $this->myOwnerDocument->renameNode($this->myDOMNode,$this->myDOMNode->namespaceURI,$name);}
319         function set_namespace($uri,$prefix=null)
320         {//Contributions by Daniel Walker 2006-09-08
321                 $nsprefix=$this->myDOMNode->lookupPrefix($uri);
322                 if ($nsprefix==null)
323                 {
324                         $nsprefix= $prefix==null ? $nsprefix='a'.sprintf('%u',crc32($uri)) : $prefix;
325                         if ($this->myDOMNode->nodeType===XML_ATTRIBUTE_NODE)
326                         {
327                                 if (($prefix!=null)&&$this->myDOMNode->ownerElement->hasAttributeNS('http://www.w3.org/2000/xmlns/',$nsprefix)&&
328                                         ($this->myDOMNode->ownerElement->getAttributeNS('http://www.w3.org/2000/xmlns/',$nsprefix)!=$uri))
329                                 {//Remove namespace
330                                         $parent=$this->myDOMNode->ownerElement;
331                                         $parent->removeAttributeNode($this->myDOMNode);
332                                         $parent->setAttribute($this->myDOMNode->localName,$this->myDOMNode->nodeValue);
333                                         $this->myDOMNode=$parent->getAttributeNode($this->myDOMNode->localName);
334                                         return;
335                                 }
336                                 $this->myDOMNode->ownerElement->setAttributeNS('http://www.w3.org/2000/xmlns/','xmlns:'.$nsprefix,$uri);
337                         }
338                 }
339                 if ($this->myDOMNode->nodeType===XML_ATTRIBUTE_NODE)
340                 {
341                         $parent=$this->myDOMNode->ownerElement;
342                         $parent->removeAttributeNode($this->myDOMNode);
343                         $parent->setAttributeNS($uri,$nsprefix.':'.$this->myDOMNode->localName,$this->myDOMNode->nodeValue);
344                         $this->myDOMNode=$parent->getAttributeNodeNS($uri,$this->myDOMNode->localName);
345                 }
346                 elseif ($this->myDOMNode->nodeType===XML_ELEMENT_NODE)
347                 {
348                         $NewNode=$this->myDOMNode->ownerDocument->createElementNS($uri,$nsprefix.':'.$this->myDOMNode->localName);
349                         foreach ($this->myDOMNode->attributes as $n) $NewNode->appendChild($n->cloneNode(true));
350                         foreach ($this->myDOMNode->childNodes as $n) $NewNode->appendChild($n->cloneNode(true));
351                         $xpath=new DOMXPath($this->myDOMNode->ownerDocument);
352                         $myDOMNodeList=$xpath->query('namespace::*[name()!="xml"]',$this->myDOMNode); //Add old namespaces
353                         foreach ($myDOMNodeList as $n) $NewNode->setAttributeNS('http://www.w3.org/2000/xmlns/',$n->nodeName,$n->nodeValue); 
354                         $this->myDOMNode->parentNode->replaceChild($NewNode,$this->myDOMNode);
355                         $this->myDOMNode=$NewNode;
356                 }
357         }
358         function unlink_node()
359         {
360                 if ($this->myDOMNode->parentNode!=null)
361                 {
362                         if ($this->myDOMNode->nodeType===XML_ATTRIBUTE_NODE) $this->myDOMNode->parentNode->removeAttributeNode($this->myDOMNode);
363                         else $this->myDOMNode->parentNode->removeChild($this->myDOMNode);
364                 }
365         }
366         protected function _importNode($newnode) {return $this->myOwnerDocument===$newnode->myOwnerDocument ? $newnode->myDOMNode : $this->myOwnerDocument->myDOMNode->importNode($newnode->myDOMNode,true);} //To import DOMNode from another DOMDocument
367         static function _newDOMElement($aDOMNode,$aOwnerDocument)
368         {//Check the PHP5 DOMNode before creating a new associated PHP4 DOMNode wrapper
369                 if ($aDOMNode==null) return null;
370                 switch ($aDOMNode->nodeType)
371                 {
372                         case XML_ELEMENT_NODE: return new php4DOMElement($aDOMNode,$aOwnerDocument);
373                         case XML_TEXT_NODE: return new php4DOMText($aDOMNode,$aOwnerDocument);
374                         case XML_ATTRIBUTE_NODE: return new php4DOMAttr($aDOMNode,$aOwnerDocument);
375                         case XML_PI_NODE: return new php4DomProcessingInstruction($aDOMNode,$aOwnerDocument);
376                         default: return new php4DOMNode($aDOMNode,$aOwnerDocument);
377                 }
378         }
379 }
380
381 class php4DomProcessingInstruction extends php4DOMNode
382 {
383         function data() {return $this->myDOMNode->data;}
384         function target() {return $this->myDOMNode->target;}
385 }
386
387 class php4DOMText extends php4DOMNode
388 {
389         function __get($name)
390         {
391                 if ($name==='tagname') return '#text';
392                 else return parent::__get($name);
393         }
394         function tagname() {return '#text';}
395         function set_content($text) {$this->myDOMNode->nodeValue=$text; return true;}
396 }
397
398 if (!defined('XPATH_NODESET'))
399 {
400         define('XPATH_UNDEFINED',0);
401         define('XPATH_NODESET',1);
402         define('XPATH_BOOLEAN',2);
403         define('XPATH_NUMBER',3);
404         define('XPATH_STRING',4);
405         /*define('XPATH_POINT',5);
406         define('XPATH_RANGE',6);
407         define('XPATH_LOCATIONSET',7);
408         define('XPATH_USERS',8);
409         define('XPATH_XSLT_TREE',9);*/
410 }
411
412 class php4DOMNodelist
413 {
414         private $myDOMNodelist;
415         public $nodeset;
416         public $type=XPATH_UNDEFINED;
417         public $value;
418         function php4DOMNodelist($aDOMNodelist,$aOwnerDocument)
419         {
420                 if (!isset($aDOMNodelist)) return; 
421                 elseif (is_object($aDOMNodelist)||is_array($aDOMNodelist))
422                 {
423                         if ($aDOMNodelist->length>0)
424                         {
425                                 $this->myDOMNodelist=$aDOMNodelist;
426                                 $this->nodeset=array();
427                                 $this->type=XPATH_NODESET;
428                                 $i=0;
429                                 while ($node=$this->myDOMNodelist->item($i++)) $this->nodeset[]=php4DOMNode::_newDOMElement($node,$aOwnerDocument);
430                         }
431                 }
432                 elseif (is_int($aDOMNodelist)||is_float($aDOMNodelist))
433                 {
434                         $this->type=XPATH_NUMBER;
435                         $this->value=$aDOMNodelist;
436                 }
437                 elseif (is_bool($aDOMNodelist))
438                 {
439                         $this->type=XPATH_BOOLEAN;
440                         $this->value=$aDOMNodelist;
441                 }
442                 elseif (is_string($aDOMNodelist))
443                 {
444                         $this->type=XPATH_STRING;
445                         $this->value=$aDOMNodelist;
446                 }
447         }
448 }
449
450 class php4DOMXPath
451 {
452         public $myDOMXPath;
453         private $myOwnerDocument;
454         function php4DOMXPath($dom_document)
455         {
456                 //TODO: If $dom_document is a DomElement, make that default $contextnode and modify XPath. Ex: '/test'
457                 $this->myOwnerDocument=$dom_document->myOwnerDocument;
458                 $this->myDOMXPath=new DOMXPath($this->myOwnerDocument->myDOMNode);
459         }
460         function xpath_eval($eval_str,$contextnode=null)
461         {
462                 if (method_exists($this->myDOMXPath,'evaluate')) $xp=isset($contextnode->myDOMNode) ? $this->myDOMXPath->evaluate($eval_str,$contextnode->myDOMNode) : $this->myDOMXPath->evaluate($eval_str);
463                 else $xp=isset($contextnode->myDOMNode) ? $this->myDOMXPath->query($eval_str,$contextnode->myDOMNode) : $this->myDOMXPath->query($eval_str);
464                 $xp=new php4DOMNodelist($xp,$this->myOwnerDocument);
465                 return ($xp->type===XPATH_UNDEFINED) ? false : $xp;
466         }
467         function xpath_register_ns($prefix,$namespaceURI) {return $this->myDOMXPath->registerNamespace($prefix,$namespaceURI);}
468 }
469
470 if (extension_loaded('xsl'))
471 {//See also: http://alexandre.alapetite.fr/doc-alex/xslt-php4-php5/
472         function domxml_xslt_stylesheet($xslstring) {return new php4DomXsltStylesheet(DOMDocument::loadXML($xslstring));}
473         function domxml_xslt_stylesheet_doc($dom_document) {return new php4DomXsltStylesheet($dom_document);}
474         function domxml_xslt_stylesheet_file($xslfile) {return new php4DomXsltStylesheet(DOMDocument::load($xslfile));}
475         class php4DomXsltStylesheet
476         {
477                 private $myxsltProcessor;
478                 function php4DomXsltStylesheet($dom_document)
479                 {
480                         $this->myxsltProcessor=new xsltProcessor();
481                         $this->myxsltProcessor->importStyleSheet($dom_document);
482                 }
483                 function process($dom_document,$xslt_parameters=array(),$param_is_xpath=false)
484                 {
485                         foreach ($xslt_parameters as $param=>$value) $this->myxsltProcessor->setParameter('',$param,$value);
486                         $myphp4DOMDocument=new php4DOMDocument();
487                         $myphp4DOMDocument->myDOMNode=$this->myxsltProcessor->transformToDoc($dom_document->myDOMNode);
488                         return $myphp4DOMDocument;
489                 }
490                 function result_dump_file($dom_document,$filename)
491                 {
492                         $html=$dom_document->myDOMNode->saveHTML();
493                         file_put_contents($filename,$html);
494                         return $html;
495                 }
496                 function result_dump_mem($dom_document) {return $dom_document->myDOMNode->saveHTML();}
497         }
498 }
499 ?>