3680 lines
107 KiB
PHP
3680 lines
107 KiB
PHP
|
|
<?php
|
||
|
|
/**
|
||
|
|
* DOMIT! is a non-validating, but lightweight and fast DOM parser for PHP
|
||
|
|
* @package domit-xmlparser
|
||
|
|
* @subpackage domit-xmlparser-main
|
||
|
|
* @version 1.01
|
||
|
|
* @copyright (C) 2004 John Heinstein. All rights reserved
|
||
|
|
* @license http://www.gnu.org/copyleft/lesser.html LGPL License
|
||
|
|
* @author John Heinstein <johnkarl@nbnet.nb.ca>
|
||
|
|
* @link http://www.engageinteractive.com/domit/ DOMIT! Home Page
|
||
|
|
* DOMIT! is Free Software
|
||
|
|
**/
|
||
|
|
|
||
|
|
if (!defined('DOMIT_INCLUDE_PATH')) {
|
||
|
|
define('DOMIT_INCLUDE_PATH', (dirname(__FILE__) . "/"));
|
||
|
|
}
|
||
|
|
|
||
|
|
/** current version of DOMIT! */
|
||
|
|
define ('DOMIT_VERSION', '1.01');
|
||
|
|
|
||
|
|
/** XML namespace URI */
|
||
|
|
define ('DOMIT_XML_NAMESPACE', 'http://www.w3.org/xml/1998/namespace');
|
||
|
|
|
||
|
|
/** XMLNS namespace URI */
|
||
|
|
define ('DOMIT_XMLNS_NAMESPACE', 'http://www.w3.org/2000/xmlns/');
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @global array Flipped version of $definedEntities array, to allow two-way conversion of entities
|
||
|
|
*
|
||
|
|
* Made global so that Attr nodes, which have no ownerDocument property, can access the array
|
||
|
|
*/
|
||
|
|
$GLOBALS['DOMIT_defined_entities_flip'] = array();
|
||
|
|
|
||
|
|
require_once(DOMIT_INCLUDE_PATH . 'xml_domit_shared.php');
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The base class of all DOMIT node types
|
||
|
|
*
|
||
|
|
* @package domit-xmlparser
|
||
|
|
* @subpackage domit-xmlparser-main
|
||
|
|
* @author John Heinstein <johnkarl@nbnet.nb.ca>
|
||
|
|
*/
|
||
|
|
class DOMIT_Node {
|
||
|
|
/** @var string The name of the node, varies according to node type */
|
||
|
|
var $nodeName = null;
|
||
|
|
/** @var string The value of the node, varies according to node type */
|
||
|
|
var $nodeValue = null;
|
||
|
|
/** @var int The type of node, e.g. CDataSection */
|
||
|
|
var $nodeType = null;
|
||
|
|
/** @var Object A reference to the parent of the current node */
|
||
|
|
var $parentNode = null;
|
||
|
|
/** @var Array An array of child node references */
|
||
|
|
var $childNodes = null;
|
||
|
|
/** @var Object A reference to the first node in the childNodes list */
|
||
|
|
var $firstChild = null;
|
||
|
|
/** @var Object A reference to the last node in the childNodes list */
|
||
|
|
var $lastChild = null;
|
||
|
|
/** @var Object A reference to the node prior to the current node in its parents childNodes list */
|
||
|
|
var $previousSibling = null;
|
||
|
|
/** @var Object A reference to the node after the current node in its parents childNodes list */
|
||
|
|
var $nextSibling = null;
|
||
|
|
/** @var Object A NodeList of attribute nodes */
|
||
|
|
var $attributes = null;
|
||
|
|
/** @var Object A reference to the Document node */
|
||
|
|
var $ownerDocument = null;
|
||
|
|
/** @var String A URI that identifies the XML namespace to which the node belongs */
|
||
|
|
var $namespaceURI = null;
|
||
|
|
/** @var String The namespace prefix for the node */
|
||
|
|
var $prefix = null;
|
||
|
|
/** @var String The local name of the node */
|
||
|
|
var $localName = null;
|
||
|
|
/** @var string The unique node id */
|
||
|
|
var $uid;
|
||
|
|
/** @var int The number of children of the current node */
|
||
|
|
var $childCount = 0;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Raises error if abstract class is directly instantiated
|
||
|
|
*/
|
||
|
|
function DOMIT_Node() {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_ABSTRACT_CLASS_INSTANTIATION_ERR,
|
||
|
|
'Cannot instantiate abstract class DOMIT_Node');
|
||
|
|
} //DOMIT_Node
|
||
|
|
|
||
|
|
/**
|
||
|
|
* DOMIT_Node constructor, assigns a uid
|
||
|
|
*/
|
||
|
|
function _constructor() {
|
||
|
|
global $uidFactory;
|
||
|
|
$this->uid = $uidFactory->generateUID();
|
||
|
|
} //_constructor
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Appends a node to the childNodes list of the current node
|
||
|
|
* @abstract
|
||
|
|
* @param Object The node to be appended
|
||
|
|
* @return Object The appended node
|
||
|
|
*/
|
||
|
|
function &appendChild(&$child) {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR,
|
||
|
|
('Method appendChild cannot be called by class ' . get_class($this)));
|
||
|
|
} //appendChild
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Inserts a node to the childNodes list of the current node
|
||
|
|
* @abstract
|
||
|
|
* @param Object The node to be inserted
|
||
|
|
* @param Object The node before which the insertion is to occur
|
||
|
|
* @return Object The inserted node
|
||
|
|
*/
|
||
|
|
function &insertBefore(&$newChild, &$refChild) {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR,
|
||
|
|
('Method insertBefore cannot be called by class ' . get_class($this)));
|
||
|
|
} //insertBefore
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Replaces a node with another
|
||
|
|
* @abstract
|
||
|
|
* @param Object The new node
|
||
|
|
* @param Object The old node
|
||
|
|
* @return Object The new node
|
||
|
|
*/
|
||
|
|
function &replaceChild(&$newChild, &$oldChild) {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR,
|
||
|
|
('Method replaceChild cannot be called by class ' . get_class($this)));
|
||
|
|
} //replaceChild
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Removes a node from the childNodes list of the current node
|
||
|
|
* @abstract
|
||
|
|
* @param Object The node to be removed
|
||
|
|
* @return Object The removed node
|
||
|
|
*/
|
||
|
|
function &removeChild(&$oldChild) {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR,
|
||
|
|
('Method removeChild cannot be called by class ' . get_class($this)));
|
||
|
|
} //removeChild
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the index of the specified node in a childNodes list
|
||
|
|
* @param Array The childNodes array to be searched
|
||
|
|
* @param Object The node targeted by the search
|
||
|
|
* @return int The index of the target node, or -1 if not found
|
||
|
|
*/
|
||
|
|
function getChildNodeIndex(&$arr, &$child) {
|
||
|
|
$index = -1;
|
||
|
|
$total = count($arr);
|
||
|
|
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
if ($child->uid == $arr[$i]->uid) {
|
||
|
|
$index = $i;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return $index;
|
||
|
|
} //getChildNodeIndex
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Determines whether a node has any children
|
||
|
|
* @return boolean True if any child nodes are present
|
||
|
|
*/
|
||
|
|
function hasChildNodes() {
|
||
|
|
return ($this->childCount > 0);
|
||
|
|
} //hasChildNodes
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Determines whether a node has any attributes
|
||
|
|
* @return boolean True if the node has attributes
|
||
|
|
*/
|
||
|
|
function hasAttributes() {
|
||
|
|
//overridden in DOMIT_Element
|
||
|
|
return false;
|
||
|
|
} //hasChildNodes
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Collapses adjacent text nodes in entire node subtree
|
||
|
|
*/
|
||
|
|
function normalize() {
|
||
|
|
if (($this->nodeType == DOMIT_DOCUMENT_NODE) && ($this->documentElement != null)) {
|
||
|
|
$this->documentElement->normalize();
|
||
|
|
}
|
||
|
|
} //normalize
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Copies a node and/or its children
|
||
|
|
* @abstract
|
||
|
|
* @param boolean True if all child nodes are also to be cloned
|
||
|
|
* @return Object A copy of the node and/or its children
|
||
|
|
*/
|
||
|
|
function &cloneNode($deep = false) {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_ABSTRACT_METHOD_INVOCATION_ERR,
|
||
|
|
'Cannot invoke abstract method DOMIT_Node->cloneNode($deep). Must provide an overridden method in your subclass.');
|
||
|
|
} //cloneNode
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Adds elements with the specified tag name to a NodeList collection
|
||
|
|
* @param Object The NodeList collection
|
||
|
|
* @param string The tag name of matching elements
|
||
|
|
*/
|
||
|
|
function getNamedElements(&$nodeList, $tagName) {
|
||
|
|
//Implemented in DOMIT_Element.
|
||
|
|
//Needs to be here though! This is called against all nodes in the document.
|
||
|
|
} //getNamedElements
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Sets the ownerDocument property of a node to the containing DOMIT_Document
|
||
|
|
* @param Object A reference to the document element of the DOMIT_Document
|
||
|
|
*/
|
||
|
|
function setOwnerDocument(&$rootNode) {
|
||
|
|
if ($rootNode->ownerDocument == null) {
|
||
|
|
unset($this->ownerDocument);
|
||
|
|
$this->ownerDocument = null;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$this->ownerDocument =& $rootNode->ownerDocument;
|
||
|
|
}
|
||
|
|
|
||
|
|
$total = $this->childCount;
|
||
|
|
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
$this->childNodes[$i]->setOwnerDocument($rootNode);
|
||
|
|
}
|
||
|
|
} //setOwnerDocument
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Tests whether a value is null, and if so, returns a default value
|
||
|
|
* @param mixed The value to be tested
|
||
|
|
* @param mixed The default value
|
||
|
|
* @return mixed The specified value, or the default value if null
|
||
|
|
*/
|
||
|
|
function &nvl(&$value,$default) {
|
||
|
|
if (is_null($value)) return $default;
|
||
|
|
return $value;
|
||
|
|
} //nvl
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Retrieves an element or DOMIT_NodeList of elements corresponding to an Xpath-like expression.
|
||
|
|
* @abstract
|
||
|
|
* @param string The query pattern
|
||
|
|
* @param int If a single node is to be returned (rather than the entire NodeList) the index of that node
|
||
|
|
* @return mixed A NodeList or single node that matches the pattern
|
||
|
|
*/
|
||
|
|
function &getElementsByPath($pattern, $nodeIndex = 0) {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR,
|
||
|
|
('Method getElementsByPath cannot be called by class ' . get_class($this)));
|
||
|
|
} //getElementsByPath
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Retrieves an element or DOMIT_NodeList of elements corresponding to an Xpath-like attribute expression (NOT YET IMPLEMENTED!)
|
||
|
|
* @abstract
|
||
|
|
* @param string The query pattern
|
||
|
|
* @param int If a single node is to be returned (rather than the entire NodeList) the index of that node
|
||
|
|
* @return mixed A NodeList or single node that matches the pattern
|
||
|
|
*/
|
||
|
|
function &getElementsByAttributePath($pattern, $nodeIndex = 0) {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR,
|
||
|
|
('Method getElementsByAttributePath cannot be called by class ' . get_class($this)));
|
||
|
|
} //getElementsByAttributePath
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Adds all child nodes of the specified nodeType to the NodeList
|
||
|
|
* @abstract
|
||
|
|
* @param Object The NodeList collection
|
||
|
|
* @param string The nodeType of matching nodes
|
||
|
|
*/
|
||
|
|
function getTypedNodes(&$nodeList, $type) {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR,
|
||
|
|
('Method getTypedNodes cannot be called by class ' . get_class($this)));
|
||
|
|
} //getTypedNodes
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Adds all child nodes of the specified nodeValue to the NodeList
|
||
|
|
* @abstract
|
||
|
|
* @param Object The NodeList collection
|
||
|
|
* @param string The nodeValue of matching nodes
|
||
|
|
*/
|
||
|
|
function getValuedNodes(&$nodeList, $value) {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR,
|
||
|
|
('Method getValuedNodes cannot be called by class ' . get_class($this)));
|
||
|
|
} //getValuedNodes
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the concatented text of the current node and its children
|
||
|
|
* @return string The concatented text of the current node and its children
|
||
|
|
*/
|
||
|
|
function getText() {
|
||
|
|
return $this->nodeValue;
|
||
|
|
} //getText
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Indicates whether the specified feature is supported by the DOM implementation and this node
|
||
|
|
* @param string The feature
|
||
|
|
* @param string The version of the DOM implementation
|
||
|
|
* @return boolean True if the specified feature is supported
|
||
|
|
*/
|
||
|
|
function isSupported($feature, $version = null) {
|
||
|
|
//don't worry about parsing based on version at this point in time;
|
||
|
|
//the only feature that is supported is 'XML'...
|
||
|
|
if (($version == '1.0') || ($version == '2.0') || ($version == null)) {
|
||
|
|
if (strtoupper($feature) == 'XML') {
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return false;
|
||
|
|
} //isSupported
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Formats a string for presentation as HTML
|
||
|
|
* @param string The string to be formatted
|
||
|
|
* @param boolean True if the string is to be sent directly to output
|
||
|
|
* @return string The HTML formatted string
|
||
|
|
*/
|
||
|
|
function forHTML($str, $doPrint = false) {
|
||
|
|
require_once(DOMIT_INCLUDE_PATH . 'xml_domit_utilities.php');
|
||
|
|
return DOMIT_Utilities::forHTML($str, $doPrint);
|
||
|
|
} //forHTML
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates an array representation of the node and its children
|
||
|
|
* @abstract
|
||
|
|
* @return Array A representation of the node and its children
|
||
|
|
*/
|
||
|
|
function toArray() {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR,
|
||
|
|
('Method toArray cannot be called by class ' . get_class($this)));
|
||
|
|
} //toArray
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A node event that can be set to fire upon document loading, used for node initialization
|
||
|
|
* @abstract
|
||
|
|
*/
|
||
|
|
function onLoad() {
|
||
|
|
//you can override this method if you subclass any of the
|
||
|
|
//DOMIT_Nodes. It's a way of performing
|
||
|
|
//initialization of your subclass as soon as the document
|
||
|
|
//has been loaded (as opposed to as soon as the current node
|
||
|
|
//has been instantiated).
|
||
|
|
} //onLoad
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Clears previousSibling, nextSibling, and parentNode references from a node that has been removed
|
||
|
|
*/
|
||
|
|
function clearReferences() {
|
||
|
|
if ($this->previousSibling != null) {
|
||
|
|
unset($this->previousSibling);
|
||
|
|
$this->previousSibling = null;
|
||
|
|
}
|
||
|
|
if ($this->nextSibling != null) {
|
||
|
|
unset($this->nextSibling);
|
||
|
|
$this->nextSibling = null;
|
||
|
|
}
|
||
|
|
if ($this->parentNode != null) {
|
||
|
|
unset($this->parentNode);
|
||
|
|
$this->parentNode = null;
|
||
|
|
}
|
||
|
|
} //clearReferences
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Removes the node from the document
|
||
|
|
*/
|
||
|
|
function delete () {
|
||
|
|
if ($this->parentNode != null) {
|
||
|
|
$this->parentNode->removeChild($node);
|
||
|
|
}
|
||
|
|
} //delete
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates a normalized (formatted for readability) representation of the node and its children
|
||
|
|
* @param boolean True if HTML readable output is desired
|
||
|
|
* @param boolean True if illegal xml characters in text nodes and attributes should be converted to entities
|
||
|
|
* @return string The formatted string representation
|
||
|
|
*/
|
||
|
|
function toNormalizedString($htmlSafe = false, $subEntities = false) {
|
||
|
|
//require this file for generating a normalized (readable) xml string representation
|
||
|
|
require_once(DOMIT_INCLUDE_PATH . 'xml_domit_utilities.php');
|
||
|
|
global $DOMIT_defined_entities_flip;
|
||
|
|
|
||
|
|
$result = DOMIT_Utilities::toNormalizedString($this, $subEntities, $DOMIT_defined_entities_flip);
|
||
|
|
|
||
|
|
if ($htmlSafe) $result = $this->forHTML($result);
|
||
|
|
|
||
|
|
return $result;
|
||
|
|
} //toNormalizedString
|
||
|
|
} //DOMIT_Node
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A parent class for nodes which possess child nodes
|
||
|
|
*
|
||
|
|
* @package domit-xmlparser
|
||
|
|
* @subpackage domit-xmlparser-main
|
||
|
|
* @author John Heinstein <johnkarl@nbnet.nb.ca>
|
||
|
|
*/
|
||
|
|
class DOMIT_ChildNodes_Interface extends DOMIT_Node {
|
||
|
|
/**
|
||
|
|
* Raises error if abstract class is directly instantiated
|
||
|
|
*/
|
||
|
|
function DOMIT_ChildNodes_Interface() {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_ABSTRACT_CLASS_INSTANTIATION_ERR,
|
||
|
|
'Cannot instantiate abstract class DOMIT_ChildNodes_Interface');
|
||
|
|
} //DOMIT_ChildNodes_Interface
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Appends a node to the childNodes list of the current node
|
||
|
|
* @param Object The node to be appended
|
||
|
|
* @return Object The appended node
|
||
|
|
*/
|
||
|
|
function &appendChild(&$child) {
|
||
|
|
if ($child->nodeType == DOMIT_ATTRIBUTE_NODE) {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR,
|
||
|
|
('Cannot add a node of type ' . get_class($child) . ' using appendChild'));
|
||
|
|
}
|
||
|
|
else if ($child->nodeType == DOMIT_DOCUMENT_FRAGMENT_NODE) {
|
||
|
|
$total = $child->childCount;
|
||
|
|
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
$currChild =& $child->childNodes[$i];
|
||
|
|
$this->appendChild($currChild);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (!($this->hasChildNodes())) {
|
||
|
|
$this->childNodes[0] =& $child;
|
||
|
|
$this->firstChild =& $child;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
//remove $child if it already exists
|
||
|
|
$index = $this->getChildNodeIndex($this->childNodes, $child);
|
||
|
|
|
||
|
|
if ($index != -1) {
|
||
|
|
$this->removeChild($child);
|
||
|
|
}
|
||
|
|
|
||
|
|
//append child
|
||
|
|
$numNodes = $this->childCount;
|
||
|
|
//BB: was bug auto-created wrong childnodes[-1]: added IF
|
||
|
|
if ($numNodes > 0) {
|
||
|
|
$prevSibling =& $this->childNodes[($numNodes - 1)];
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->childNodes[$numNodes] =& $child;
|
||
|
|
|
||
|
|
//set next and previous relationships
|
||
|
|
//BB: added this line and the else part to finish correcting bug
|
||
|
|
if (isset( $prevSibling )) {
|
||
|
|
$child->previousSibling =& $prevSibling;
|
||
|
|
$prevSibling->nextSibling =& $child;
|
||
|
|
} else {
|
||
|
|
unset( $child->previousSibling );
|
||
|
|
$child->previousSibling = null;
|
||
|
|
$this->firstChild =& $child;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->lastChild =& $child;
|
||
|
|
$child->parentNode =& $this;
|
||
|
|
|
||
|
|
unset($child->nextSibling);
|
||
|
|
$child->nextSibling = null;
|
||
|
|
|
||
|
|
$child->setOwnerDocument($this);
|
||
|
|
$this->childCount++;
|
||
|
|
|
||
|
|
return $child;
|
||
|
|
|
||
|
|
} //appendChild
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Inserts a node to the childNodes list of the current node
|
||
|
|
* @param Object The node to be inserted
|
||
|
|
* @param Object The node before which the insertion is to occur
|
||
|
|
* @return Object The inserted node
|
||
|
|
*/
|
||
|
|
function &insertBefore(&$newChild, &$refChild) {
|
||
|
|
if ($newChild->nodeType == DOMIT_ATTRIBUTE_NODE) {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR,
|
||
|
|
('Cannot add a node of type ' . get_class($newChild) . ' using insertBefore'));
|
||
|
|
}
|
||
|
|
|
||
|
|
if (($refChild->nodeType == DOMIT_DOCUMENT_NODE) ||
|
||
|
|
//($refChild->parentNode->nodeType == DOMIT_DOCUMENT_NODE) ||
|
||
|
|
($refChild->parentNode == null)) {
|
||
|
|
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_NOT_FOUND_ERR,
|
||
|
|
'Reference child not present in the child nodes list.');
|
||
|
|
}
|
||
|
|
|
||
|
|
//if reference child is also the node to be inserted
|
||
|
|
//leave the document as is and don't raise an exception
|
||
|
|
if ($refChild->uid == $newChild->uid) {
|
||
|
|
return $newChild;
|
||
|
|
}
|
||
|
|
|
||
|
|
//if $newChild is a DocumentFragment,
|
||
|
|
//loop through and insert each node separately
|
||
|
|
if ($newChild->nodeType == DOMIT_DOCUMENT_FRAGMENT_NODE) {
|
||
|
|
$total = $newChild->childCount;
|
||
|
|
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
$currChild =& $newChild->childNodes[$i];
|
||
|
|
$this->insertBefore($currChild, $refChild);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $newChild;
|
||
|
|
}
|
||
|
|
|
||
|
|
//remove $newChild if it already exists
|
||
|
|
$index = $this->getChildNodeIndex($this->childNodes, $newChild);
|
||
|
|
if ($index != -1) {
|
||
|
|
$this->removeChild($newChild);
|
||
|
|
}
|
||
|
|
|
||
|
|
//find index of $refChild in childNodes
|
||
|
|
$index = $this->getChildNodeIndex($this->childNodes, $refChild);
|
||
|
|
|
||
|
|
if ($index != -1) {
|
||
|
|
//reset sibling chain
|
||
|
|
if ($refChild->previousSibling != null) {
|
||
|
|
$refChild->previousSibling->nextSibling =& $newChild;
|
||
|
|
$newChild->previousSibling =& $refChild->previousSibling;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$this->firstChild =& $newChild;
|
||
|
|
|
||
|
|
if ($newChild->previousSibling != null) {
|
||
|
|
unset($newChild->previousSibling);
|
||
|
|
$newChild->previousSibling = null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$newChild->parentNode =& $refChild->parentNode;
|
||
|
|
$newChild->nextSibling =& $refChild;
|
||
|
|
$refChild->previousSibling =& $newChild;
|
||
|
|
|
||
|
|
//add node to childNodes
|
||
|
|
$i = $this->childCount;
|
||
|
|
|
||
|
|
while ($i >= 0) {
|
||
|
|
if ($i > $index) {
|
||
|
|
$this->childNodes[$i] =& $this->childNodes[($i - 1)];
|
||
|
|
}
|
||
|
|
else if ($i == $index) {
|
||
|
|
$this->childNodes[$i] =& $newChild;
|
||
|
|
}
|
||
|
|
$i--;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->childCount++;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$this->appendChild($newChild);
|
||
|
|
}
|
||
|
|
|
||
|
|
$newChild->setOwnerDocument($this);
|
||
|
|
return $newChild;
|
||
|
|
} //insertBefore
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Replaces a node with another
|
||
|
|
* @param Object The new node
|
||
|
|
* @param Object The old node
|
||
|
|
* @return Object The new node
|
||
|
|
*/
|
||
|
|
function &replaceChild(&$newChild, &$oldChild) {
|
||
|
|
if ($newChild->nodeType == DOMIT_ATTRIBUTE_NODE) {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR,
|
||
|
|
('Cannot add a node of type ' . get_class($newChild) . ' using replaceChild'));
|
||
|
|
}
|
||
|
|
else if ($newChild->nodeType == DOMIT_DOCUMENT_FRAGMENT_NODE) { //if $newChild is a DocumentFragment
|
||
|
|
//replace the first node then loop through and insert each node separately
|
||
|
|
$total = $newChild->childCount;
|
||
|
|
|
||
|
|
if ($total > 0) {
|
||
|
|
$newRef =& $newChild->lastChild;
|
||
|
|
$this->replaceChild($newRef, $oldChild);
|
||
|
|
|
||
|
|
for ($i = 0; $i < ($total - 1); $i++) {
|
||
|
|
$currChild =& $newChild->childNodes[$i];
|
||
|
|
$this->insertBefore($currChild, $newRef);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return $newChild;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if ($this->hasChildNodes()) {
|
||
|
|
//remove $newChild if it already exists
|
||
|
|
$index = $this->getChildNodeIndex($this->childNodes, $newChild);
|
||
|
|
if ($index != -1) {
|
||
|
|
$this->removeChild($newChild);
|
||
|
|
}
|
||
|
|
|
||
|
|
//find index of $oldChild in childNodes
|
||
|
|
$index = $this->getChildNodeIndex($this->childNodes, $oldChild);
|
||
|
|
|
||
|
|
if ($index != -1) {
|
||
|
|
$newChild->ownerDocument =& $oldChild->ownerDocument;
|
||
|
|
$newChild->parentNode =& $oldChild->parentNode;
|
||
|
|
|
||
|
|
//reset sibling chain
|
||
|
|
if ($oldChild->previousSibling == null) {
|
||
|
|
unset($newChild->previousSibling);
|
||
|
|
$newChild->previousSibling = null;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$oldChild->previousSibling->nextSibling =& $newChild;
|
||
|
|
$newChild->previousSibling =& $oldChild->previousSibling;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($oldChild->nextSibling == null) {
|
||
|
|
unset($newChild->nextSibling);
|
||
|
|
$newChild->nextSibling = null;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$oldChild->nextSibling->previousSibling =& $newChild;
|
||
|
|
$newChild->nextSibling =& $oldChild->nextSibling;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->childNodes[$index] =& $newChild;
|
||
|
|
|
||
|
|
if ($index == 0) $this->firstChild =& $newChild;
|
||
|
|
if ($index == ($this->childCount - 1)) $this->lastChild =& $newChild;
|
||
|
|
|
||
|
|
$newChild->setOwnerDocument($this);
|
||
|
|
return $newChild;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_NOT_FOUND_ERR,
|
||
|
|
('Reference node for replaceChild not found.'));
|
||
|
|
}
|
||
|
|
} //replaceChild
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Removes a node from the childNodes list of the current node
|
||
|
|
* @param Object The node to be removed
|
||
|
|
* @return Object The removed node
|
||
|
|
*/
|
||
|
|
function &removeChild(&$oldChild) {
|
||
|
|
if ($this->hasChildNodes()) {
|
||
|
|
//find index of $oldChild in childNodes
|
||
|
|
$index = $this->getChildNodeIndex($this->childNodes, $oldChild);
|
||
|
|
|
||
|
|
if ($index != -1) {
|
||
|
|
//reset sibling chain
|
||
|
|
if (($oldChild->previousSibling != null) && ($oldChild->nextSibling != null)) {
|
||
|
|
$oldChild->previousSibling->nextSibling =& $oldChild->nextSibling;
|
||
|
|
$oldChild->nextSibling->previousSibling =& $oldChild->previousSibling;
|
||
|
|
}
|
||
|
|
else if (($oldChild->previousSibling != null) && ($oldChild->nextSibling == null)) {
|
||
|
|
$this->lastChild =& $oldChild->previousSibling;
|
||
|
|
unset($oldChild->previousSibling->nextSibling);
|
||
|
|
$oldChild->previousSibling->nextSibling = null;
|
||
|
|
}
|
||
|
|
else if (($oldChild->previousSibling == null) && ($oldChild->nextSibling != null)) {
|
||
|
|
unset($oldChild->nextSibling->previousSibling);
|
||
|
|
$oldChild->nextSibling->previousSibling = null;
|
||
|
|
$this->firstChild =& $oldChild->nextSibling;
|
||
|
|
}
|
||
|
|
else if (($oldChild->previousSibling == null) && ($oldChild->nextSibling == null)) {
|
||
|
|
unset($this->firstChild);
|
||
|
|
$this->firstChild = null;
|
||
|
|
unset($this->lastChild);
|
||
|
|
$this->lastChild = null;
|
||
|
|
}
|
||
|
|
|
||
|
|
$total = $this->childCount;
|
||
|
|
|
||
|
|
//remove node from childNodes
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
if ($i == ($total - 1)) {
|
||
|
|
array_splice($this->childNodes, $i, 1);
|
||
|
|
}
|
||
|
|
else if ($i >= $index) {
|
||
|
|
$this->childNodes[$i] =& $this->childNodes[($i + 1)];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->childCount--;
|
||
|
|
|
||
|
|
$oldChild->clearReferences();
|
||
|
|
return $oldChild;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_NOT_FOUND_ERR,
|
||
|
|
('Target node for removeChild not found.'));
|
||
|
|
} //removeChild
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Searches the element tree for an element with the specified attribute name and value.
|
||
|
|
* @param string The value of the attribute
|
||
|
|
* @param string The name of the attribute
|
||
|
|
* @param boolean True if the first found node is to be returned as a node instead of a nodelist
|
||
|
|
* @param boolean True if uid is to be considered an attribute
|
||
|
|
* @return object A NodeList of found elements, or null
|
||
|
|
*/
|
||
|
|
function &getElementsByAttribute($attrName = 'id', $attrValue = '',
|
||
|
|
$returnFirstFoundNode = false, $treatUIDAsAttribute = false) {
|
||
|
|
require_once(DOMIT_INCLUDE_PATH . 'xml_domit_nodemaps.php');
|
||
|
|
|
||
|
|
$nodelist = new DOMIT_NodeList();
|
||
|
|
|
||
|
|
switch ($this->nodeType) {
|
||
|
|
case DOMIT_ELEMENT_NODE:
|
||
|
|
$this->_getElementsByAttribute($nodelist, $attrName, $attrValue,
|
||
|
|
$returnFirstFoundNode, $treatUIDAsAttribute);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case DOMIT_DOCUMENT_NODE:
|
||
|
|
if ($this->documentElement != null) {
|
||
|
|
$this->documentElement->_getElementsByAttribute($nodelist,
|
||
|
|
$attrName, $attrValue, $returnFirstFoundNode, $treatUIDAsAttribute);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($returnFirstFoundNode) {
|
||
|
|
if ($nodelist->getLength() > 0) {
|
||
|
|
return $nodelist->item(0);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$null = null;
|
||
|
|
return $null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
return $nodelist;
|
||
|
|
}
|
||
|
|
} //getElementsByAttribute
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Searches the element tree for an element with the specified attribute name and value.
|
||
|
|
* @param object The node list of found elements
|
||
|
|
* @param string The value of the attribute
|
||
|
|
* @param string The name of the attribute
|
||
|
|
* @param boolean True if the first found node is to be returned as a node instead of a nodelist
|
||
|
|
* @param boolean True if uid is to be considered an attribute
|
||
|
|
* @param boolean True the node has been found
|
||
|
|
*/
|
||
|
|
function _getElementsByAttribute(&$nodelist, $attrName, $attrValue,
|
||
|
|
$returnFirstFoundNode, $treatUIDAsAttribute, $foundNode = false) {
|
||
|
|
if (!($foundNode && $returnFirstFoundNode)) {
|
||
|
|
if (($this->getAttribute($attrName) == $attrValue) ||
|
||
|
|
($treatUIDAsAttribute && ($attrName == 'uid') && ($this->uid == $attrValue))) {
|
||
|
|
$nodelist->appendNode($this);
|
||
|
|
$foundNode = true;
|
||
|
|
if ($returnFirstFoundNode) return;
|
||
|
|
}
|
||
|
|
|
||
|
|
$total = $this->childCount;
|
||
|
|
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
$currNode =& $this->childNodes[$i];
|
||
|
|
|
||
|
|
if ($currNode->nodeType == DOMIT_ELEMENT_NODE) {
|
||
|
|
$currNode->_getElementsByAttribute($nodelist,
|
||
|
|
$attrName, $attrValue, $returnFirstFoundNode,
|
||
|
|
$treatUIDAsAttribute, $foundNode);
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} //_getElementsByAttribute
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Performs an XPath query
|
||
|
|
* @param string The query pattern
|
||
|
|
* @return Object A NodeList containing the found nodes
|
||
|
|
*/
|
||
|
|
function &selectNodes($pattern, $nodeIndex = 0) {
|
||
|
|
require_once(DOMIT_INCLUDE_PATH . 'xml_domit_xpath.php');
|
||
|
|
|
||
|
|
$xpParser = new DOMIT_XPath();
|
||
|
|
|
||
|
|
return $xpParser->parsePattern($this, $pattern, $nodeIndex);
|
||
|
|
} //selectNodes
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Converts the childNodes array into a NodeList object
|
||
|
|
* @return Object A NodeList containing elements of the childNodes array
|
||
|
|
*/
|
||
|
|
function &childNodesAsNodeList() {
|
||
|
|
require_once('xml_domit_nodemaps.php');
|
||
|
|
$myNodeList = new DOMIT_NodeList();
|
||
|
|
|
||
|
|
$total = $this->childCount;
|
||
|
|
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
$myNodeList->appendNode($this->childNodes[$i]);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $myNodeList;
|
||
|
|
} //childNodesAsNodeList
|
||
|
|
} //DOMIT_ChildNodes_Interface
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A class representing the DOM Document
|
||
|
|
*
|
||
|
|
* @package domit-xmlparser
|
||
|
|
* @subpackage domit-xmlparser-main
|
||
|
|
* @author John Heinstein <johnkarl@nbnet.nb.ca>
|
||
|
|
*/
|
||
|
|
class DOMIT_Document extends DOMIT_ChildNodes_Interface {
|
||
|
|
/** @var Object The xml declaration processing instruction */
|
||
|
|
var $xmlDeclaration;
|
||
|
|
/** @var Object A reference to a DOMIT_DocType object */
|
||
|
|
var $doctype;
|
||
|
|
/** @var Object A reference to the root node of the DOM document */
|
||
|
|
var $documentElement;
|
||
|
|
/** @var string The parser used to process the DOM document, either "EXPAT" or "SAXY" */
|
||
|
|
var $parser;
|
||
|
|
/** @var Object A reference to the DOMIT_DOMImplementation object */
|
||
|
|
var $implementation;
|
||
|
|
/** @var boolean True if the DOM document has been modifed since being parsed (NOT YET IMPLEMENTED!) */
|
||
|
|
var $isModified;
|
||
|
|
/** @var boolean True if whitespace is to be preserved during parsing */
|
||
|
|
var $preserveWhitespace = false;
|
||
|
|
/** @var Array User defined translation table for XML entities; passed to SAXY */
|
||
|
|
var $definedEntities = array();
|
||
|
|
/** @var boolean If true, loadXML or parseXML will attempt to detect and repair invalid xml */
|
||
|
|
var $doResolveErrors = false;
|
||
|
|
/** @var boolean If true, elements tags will be rendered to string as <element></element> rather than <element/> */
|
||
|
|
var $doExpandEmptyElementTags = false;
|
||
|
|
/** @var array A list of exceptions to the empty element expansion rule */
|
||
|
|
var $expandEmptyElementExceptions = array();
|
||
|
|
/** @var boolean If true, namespaces will be processed */
|
||
|
|
var $isNamespaceAware = false;
|
||
|
|
/** @var int The error code returned by the SAX parser */
|
||
|
|
var $errorCode = 0;
|
||
|
|
/** @var string The error string returned by the SAX parser */
|
||
|
|
var $errorString = '';
|
||
|
|
/** @var object A reference to a http connection or proxy server, if one is required */
|
||
|
|
var $httpConnection = null;
|
||
|
|
/** @var boolean True if php_http_client_generic is to be used instead of PHP get_file_contents to retrieve xml data */
|
||
|
|
var $doUseHTTPClient = false;
|
||
|
|
/** @var array An array of namespacesURIs mapped to prefixes */
|
||
|
|
var $namespaceURIMap = array();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* DOM Document constructor
|
||
|
|
*/
|
||
|
|
function DOMIT_Document() {
|
||
|
|
$this->_constructor();
|
||
|
|
$this->xmlDeclaration = null;
|
||
|
|
$this->doctype = null;
|
||
|
|
$this->documentElement = null;
|
||
|
|
$this->nodeType = DOMIT_DOCUMENT_NODE;
|
||
|
|
$this->nodeName = '#document';
|
||
|
|
$this->ownerDocument =& $this;
|
||
|
|
$this->parser = '';
|
||
|
|
$this->implementation = new DOMIT_DOMImplementation();
|
||
|
|
} //DOMIT_Document
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Specifies whether DOMIT! will try to fix invalid XML before parsing begins
|
||
|
|
* @param boolean True if errors are to be resolved
|
||
|
|
*/
|
||
|
|
function resolveErrors($truthVal) {
|
||
|
|
$this->doResolveErrors = $truthVal;
|
||
|
|
} //resolveErrors
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Specifies whether DOMIT! processes namespace information
|
||
|
|
* @param boolean True if namespaces are to be processed
|
||
|
|
*/
|
||
|
|
function setNamespaceAwareness($truthVal) {
|
||
|
|
$this->isNamespaceAware = $truthVal;
|
||
|
|
} //setNamespaceAwareness
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Specifies whether DOMIT! preserves whitespace when parsing
|
||
|
|
* @param boolean True if whitespace is to be preserved
|
||
|
|
*/
|
||
|
|
function preserveWhitespace($truthVal) {
|
||
|
|
$this->preserveWhitespace = $truthVal;
|
||
|
|
} //preserveWhitespace
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Specifies the parameters of the http conection used to obtain the xml data
|
||
|
|
* @param string The ip address or domain name of the connection
|
||
|
|
* @param string The path of the connection
|
||
|
|
* @param int The port that the connection is listening on
|
||
|
|
* @param int The timeout value for the connection
|
||
|
|
* @param string The user name, if authentication is required
|
||
|
|
* @param string The password, if authentication is required
|
||
|
|
*/
|
||
|
|
function setConnection($host, $path = '/', $port = 80, $timeout = 0, $user = null, $password = null) {
|
||
|
|
require_once(DOMIT_INCLUDE_PATH . 'php_http_client_generic.php');
|
||
|
|
|
||
|
|
$this->httpConnection = new php_http_client_generic($host, $path, $port, $timeout, $user, $password);
|
||
|
|
} //setConnection
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Specifies basic authentication for an http connection
|
||
|
|
* @param string The user name
|
||
|
|
* @param string The password
|
||
|
|
*/
|
||
|
|
function setAuthorization($user, $password) {
|
||
|
|
$this->httpConnection->setAuthorization($user, $password);
|
||
|
|
} //setAuthorization
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Specifies that a proxy is to be used to obtain the xml data
|
||
|
|
* @param string The ip address or domain name of the proxy
|
||
|
|
* @param string The path to the proxy
|
||
|
|
* @param int The port that the proxy is listening on
|
||
|
|
* @param int The timeout value for the connection
|
||
|
|
* @param string The user name, if authentication is required
|
||
|
|
* @param string The password, if authentication is required
|
||
|
|
*/
|
||
|
|
function setProxyConnection($host, $path = '/', $port = 80, $timeout = 0, $user = null, $password = null) {
|
||
|
|
require_once(DOMIT_INCLUDE_PATH . 'php_http_proxy.php');
|
||
|
|
|
||
|
|
$this->httpConnection = new php_http_proxy($host, $path, $port, $timeout, $user, $password);
|
||
|
|
} //setProxyConnection
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Specifies basic authentication for the proxy
|
||
|
|
* @param string The user name
|
||
|
|
* @param string The password
|
||
|
|
*/
|
||
|
|
function setProxyAuthorization($user, $password) {
|
||
|
|
$this->httpConnection->setProxyAuthorization($user, $password);
|
||
|
|
} //setProxyAuthorization
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Specifies whether an HTTP client should be used to establish a connection
|
||
|
|
* @param boolean True if an HTTP client is to be used to establish the connection
|
||
|
|
*/
|
||
|
|
function useHTTPClient($truthVal) {
|
||
|
|
$this->doUseHTTPClient = $truthVal;
|
||
|
|
} //useHTTPClient
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the error code from the underlying SAX parser
|
||
|
|
* @return int The error code
|
||
|
|
*/
|
||
|
|
function getErrorCode() {
|
||
|
|
return $this->errorCode;
|
||
|
|
} //getErrorCode
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the error string from the underlying SAX parser
|
||
|
|
* @return string The error string
|
||
|
|
*/
|
||
|
|
function getErrorString() {
|
||
|
|
return $this->errorString;
|
||
|
|
} //getErrorString
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Specifies whether elements tags will be rendered to string as <element></element> rather than <element/>
|
||
|
|
* @param boolean True if the expanded form is to be used
|
||
|
|
* @param mixed An array of tag names that should be excepted from expandEmptyElements rule (optional)
|
||
|
|
*/
|
||
|
|
function expandEmptyElementTags($truthVal, $expandEmptyElementExceptions = false) {
|
||
|
|
$this->doExpandEmptyElementTags = $truthVal;
|
||
|
|
|
||
|
|
if (is_array($expandEmptyElementExceptions)) {
|
||
|
|
$this->expandEmptyElementExceptions = $expandEmptyElementExceptions;
|
||
|
|
}
|
||
|
|
} //expandEmptyElementTags
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set the specified node as document element
|
||
|
|
* @param Object The node that is to become document element
|
||
|
|
* @return Object The new document element
|
||
|
|
*/
|
||
|
|
function &setDocumentElement(&$node) {
|
||
|
|
if ($node->nodeType == DOMIT_ELEMENT_NODE) {
|
||
|
|
if ($this->documentElement == null) {
|
||
|
|
parent::appendChild($node);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
parent::replaceChild($node, $this->documentElement);
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->documentElement =& $node;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR,
|
||
|
|
('Cannot add a node of type ' . get_class($node) . ' as a Document Element.'));
|
||
|
|
}
|
||
|
|
|
||
|
|
return $node;
|
||
|
|
} //setDocumentElement
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Imports a node (and optionally its children) from another DOM Document
|
||
|
|
* @param object A reference to the node to be imported
|
||
|
|
* @param boolean True if the children of the imported node are also to be imported
|
||
|
|
* @return object The imported node (and, if specified, its children)
|
||
|
|
*/
|
||
|
|
function &importNode(&$importedNode, $deep = true) {
|
||
|
|
$parentNode = null;
|
||
|
|
return $this->_importNode($parentNode, $importedNode, $deep);
|
||
|
|
} //importNode
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Imports a node (and optionally its children) from another DOM Document
|
||
|
|
* @param object A reference to the parent of the node to be imported
|
||
|
|
* @param object A reference to the node to be imported
|
||
|
|
* @param boolean True if the children of the imported node are also to be imported
|
||
|
|
* @return object The imported node if it is the top level node, otherwise null
|
||
|
|
*/
|
||
|
|
function &_importNode(&$parentNode, &$sourceNode, $deep) {
|
||
|
|
$hasChildren = false;
|
||
|
|
|
||
|
|
switch ($sourceNode->nodeType) {
|
||
|
|
case DOMIT_ELEMENT_NODE:
|
||
|
|
$hasChildren = true;
|
||
|
|
|
||
|
|
if ($this->isNamespaceAware) {
|
||
|
|
$importedNode =& $this->createElementNS($sourceNode->namespaceURI,
|
||
|
|
($sourceNode->prefix . ":" . $sourceNode->localName));
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$importedNode =& $this->createElement($sourceNode->nodeName);
|
||
|
|
}
|
||
|
|
|
||
|
|
$attrNodes =& $sourceNode->attributes;
|
||
|
|
$total = $attrNodes->getLength();
|
||
|
|
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
$attrNode =& $attrNodes->item($i);
|
||
|
|
|
||
|
|
if ($this->isNamespaceAware) {
|
||
|
|
$importedNode->setAttributeNS($attrNode->namespaceURI,
|
||
|
|
($attrNode->prefix . ":" . $attrNode->localName), $attrNode->nodeValue);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$importedNode->setAttribute($attrNode->nodeName, $attrNode->nodeValue);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
break;
|
||
|
|
|
||
|
|
case DOMIT_ATTRIBUTE_NODE:
|
||
|
|
if ($this->isNamespaceAware) {
|
||
|
|
$importedNode =& $this->createAttributeNS($sourceNode->namespaceURI,
|
||
|
|
($sourceNode->prefix . ":" . $sourceNode->localName));
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$importedNode =& $this->createAttribute($sourceNode->nodeValue);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case DOMIT_TEXT_NODE:
|
||
|
|
$importedNode =& $this->createTextNode($sourceNode->nodeValue);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case DOMIT_CDATA_SECTION_NODE:
|
||
|
|
$importedNode =& $this->createCDATASection($sourceNode->nodeValue);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case DOMIT_COMMENT_NODE:
|
||
|
|
$importedNode =& $this->createComment($sourceNode->nodeValue);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case DOMIT_DOCUMENT_FRAGMENT_NODE:
|
||
|
|
$hasChildren = true;
|
||
|
|
$importedNode =& $this->createDocumentFragment();
|
||
|
|
break;
|
||
|
|
|
||
|
|
case DOMIT_PROCESSING_INSTRUCTION_NODE:
|
||
|
|
$importedNode =& $this->createProcessingInstruction($sourceNode->nodeName,
|
||
|
|
$sourceNode->nodeValue);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case DOMIT_DOCUMENT_NODE:
|
||
|
|
case DOMIT_DOCUMENT_TYPE_NODE:
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_NOT_SUPPORTED_ERR,
|
||
|
|
('Method importNode cannot be called by class ' . get_class($this)));
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($hasChildren && $deep) {
|
||
|
|
$total = $sourceNode->childCount;
|
||
|
|
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
$importedNode->appendChild(
|
||
|
|
$this->_importNode($importedNode, $sourceNode->childNodes[$i], $deep));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return $importedNode;
|
||
|
|
} //_importNode
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Appends a node to the childNodes list of the current node
|
||
|
|
* @param Object The node to be appended
|
||
|
|
* @return Object The appended node
|
||
|
|
*/
|
||
|
|
function &appendChild(&$node) {
|
||
|
|
switch ($node->nodeType) {
|
||
|
|
case DOMIT_ELEMENT_NODE:
|
||
|
|
if ($this->documentElement == null) {
|
||
|
|
parent::appendChild($node);
|
||
|
|
$this->setDocumentElement($node);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
//error thrown if documentElement already exists!
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR,
|
||
|
|
('Cannot have more than one root node (documentElement) in a DOMIT_Document.'));
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case DOMIT_PROCESSING_INSTRUCTION_NODE:
|
||
|
|
case DOMIT_COMMENT_NODE:
|
||
|
|
parent::appendChild($node);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case DOMIT_DOCUMENT_TYPE_NODE:
|
||
|
|
if ($this->doctype == null) {
|
||
|
|
parent::appendChild($node);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR,
|
||
|
|
('Cannot have more than one doctype node in a DOMIT_Document.'));
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case DOMIT_DOCUMENT_FRAGMENT_NODE:
|
||
|
|
$total = $node->childCount;
|
||
|
|
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
$currChild =& $node->childNodes[$i];
|
||
|
|
$this->appendChild($currChild);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
default:
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR,
|
||
|
|
('Cannot add a node of type ' . get_class($node) . ' to a DOMIT_Document.'));
|
||
|
|
}
|
||
|
|
|
||
|
|
return $node;
|
||
|
|
} //appendChild
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Replaces a node with another
|
||
|
|
* @param Object The new node
|
||
|
|
* @param Object The old node
|
||
|
|
* @return Object The new node
|
||
|
|
*/
|
||
|
|
function &replaceChild(&$newChild, &$oldChild) {
|
||
|
|
if ($this->nodeType == DOMIT_DOCUMENT_FRAGMENT_NODE) {
|
||
|
|
$total = $newChild->childCount;
|
||
|
|
|
||
|
|
if ($total > 0) {
|
||
|
|
$newRef =& $newChild->lastChild;
|
||
|
|
$this->replaceChild($newRef, $oldChild);
|
||
|
|
|
||
|
|
for ($i = 0; $i < ($total - 1); $i++) {
|
||
|
|
$currChild =& $newChild->childNodes[$i];
|
||
|
|
parent::insertBefore($currChild, $newRef);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (($this->documentElement != null) && ($oldChild->uid == $this->documentElement->uid)) {
|
||
|
|
if ($newChild->nodeType == DOMIT_ELEMENT_NODE) {
|
||
|
|
//replace documentElement with new node
|
||
|
|
$this->setDocumentElement($newChild);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR,
|
||
|
|
('Cannot replace Document Element with a node of class ' . get_class($newChild)));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
switch ($newChild->nodeType) {
|
||
|
|
case DOMIT_ELEMENT_NODE:
|
||
|
|
if ($this->documentElement != null) {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR,
|
||
|
|
('Cannot have more than one root node (documentElement) in a DOMIT_Document.'));
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
parent::replaceChild($newChild, $oldChild);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case DOMIT_PROCESSING_INSTRUCTION_NODE:
|
||
|
|
case DOMIT_COMMENT_NODE:
|
||
|
|
parent::replaceChild($newChild, $oldChild);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case DOMIT_DOCUMENT_TYPE_NODE:
|
||
|
|
if ($this->doctype != null) {
|
||
|
|
if ($this->doctype->uid == $oldChild->uid) {
|
||
|
|
parent::replaceChild($newChild, $oldChild);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR,
|
||
|
|
('Cannot have more than one doctype node in a DOMIT_Document.'));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
parent::replaceChild($newChild, $oldChild);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
default:
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR,
|
||
|
|
('Nodes of class ' . get_class($newChild) . ' cannot be children of a DOMIT_Document.'));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return $newChild;
|
||
|
|
} //replaceChild
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Inserts a node to the childNodes list of the current node
|
||
|
|
* @param Object The node to be inserted
|
||
|
|
* @param Object The node before which the insertion is to occur
|
||
|
|
* @return Object The inserted node
|
||
|
|
*/
|
||
|
|
function &insertBefore(&$newChild, &$refChild) {
|
||
|
|
$type = $newChild->nodeType;
|
||
|
|
|
||
|
|
if ($this->nodeType == DOMIT_DOCUMENT_FRAGMENT_NODE) {
|
||
|
|
$total = $newChild->childCount;
|
||
|
|
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
$currChild =& $newChild->childNodes[$i];
|
||
|
|
$this->insertBefore($currChild, $refChild);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if ($type == DOMIT_ELEMENT_NODE) {
|
||
|
|
if ($this->documentElement == null) {
|
||
|
|
parent::insertBefore($newChild, $refChild);
|
||
|
|
$this->setDocumentElement($newChild);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
//error thrown if documentElement already exists!
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR,
|
||
|
|
('Cannot have more than one root node (documentElement) in a DOMIT_Document.'));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if ($type == DOMIT_PROCESSING_INSTRUCTION_NODE) {
|
||
|
|
parent::insertBefore($newChild, $refChild);
|
||
|
|
}
|
||
|
|
else if ($type == DOMIT_DOCUMENT_TYPE_NODE) {
|
||
|
|
if ($this->doctype == null) {
|
||
|
|
parent::insertBefore($newChild, $refChild);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR,
|
||
|
|
('Cannot have more than one doctype node in a DOMIT_Document.'));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR,
|
||
|
|
('Cannot insert a node of type ' . get_class($newChild) . ' to a DOMIT_Document.'));
|
||
|
|
}
|
||
|
|
|
||
|
|
return $newChild;
|
||
|
|
} //insertBefore
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Removes a node from the childNodes list of the current node
|
||
|
|
* @param Object The node to be removed
|
||
|
|
* @return Object The removed node
|
||
|
|
*/
|
||
|
|
function &removeChild(&$oldChild) {
|
||
|
|
if ($this->nodeType == DOMIT_DOCUMENT_FRAGMENT_NODE) {
|
||
|
|
$total = $oldChild->childCount;
|
||
|
|
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
$currChild =& $oldChild->childNodes[$i];
|
||
|
|
$this->removeChild($currChild);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (($this->documentElement != null) && ($oldChild->uid == $this->documentElement->uid)) {
|
||
|
|
parent::removeChild($oldChild);
|
||
|
|
$this->documentElement = null;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
parent::removeChild($oldChild);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$oldChild->clearReferences();
|
||
|
|
return $oldChild;
|
||
|
|
} //removeChild
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Creates a new DOMIT_DocumentFragment node
|
||
|
|
* @return Object The new document fragment node
|
||
|
|
*/
|
||
|
|
function &createDocumentFragment() {
|
||
|
|
$node = new DOMIT_DocumentFragment();
|
||
|
|
$node->ownerDocument =& $this;
|
||
|
|
|
||
|
|
return $node;
|
||
|
|
} //createDocumentFragment
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Creates a new DOMIT_Attr node
|
||
|
|
* @param string The name of the attribute
|
||
|
|
* @return Object The new attribute node
|
||
|
|
*/
|
||
|
|
function &createAttribute($name) {
|
||
|
|
$node = new DOMIT_Attr($name);
|
||
|
|
|
||
|
|
return $node;
|
||
|
|
} //createAttribute
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Creates a new DOMIT_Attr node (namespace aware)
|
||
|
|
* @param string The namespaceURI of the attribute
|
||
|
|
* @param string The qualifiedName of the attribute
|
||
|
|
* @return Object The new attribute node
|
||
|
|
*/
|
||
|
|
function &createAttributeNS($namespaceURI, $qualifiedName) {
|
||
|
|
$node = new DOMIT_Attr($qualifiedName);
|
||
|
|
$node->namespaceURI = $namespaceURI;
|
||
|
|
|
||
|
|
$colonIndex = strpos($qualifiedName, ":");
|
||
|
|
|
||
|
|
if ($colonIndex !== false) {
|
||
|
|
$node->prefix = substr($qualifiedName, 0, $colonIndex);
|
||
|
|
$node->localName = substr($qualifiedName, ($colonIndex + 1));
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$node->prefix = '';
|
||
|
|
$node->localName = $qualifiedName;
|
||
|
|
}
|
||
|
|
|
||
|
|
return $node;
|
||
|
|
} //createAttributeNS
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Creates a new DOMIT_Element node
|
||
|
|
* @param string The tag name of the element
|
||
|
|
* @return Object The new element
|
||
|
|
*/
|
||
|
|
function &createElement($tagName) {
|
||
|
|
$node = new DOMIT_Element($tagName);
|
||
|
|
$node->ownerDocument =& $this;
|
||
|
|
|
||
|
|
return $node;
|
||
|
|
} //createElement
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Creates a new DOMIT_Element node (namespace aware)
|
||
|
|
* @param string The namespaceURI of the element
|
||
|
|
* @param string The qualifiedName of the element
|
||
|
|
* @return Object The new element
|
||
|
|
*/
|
||
|
|
function &createElementNS($namespaceURI, $qualifiedName) {
|
||
|
|
$node = new DOMIT_Element($qualifiedName);
|
||
|
|
|
||
|
|
$colonIndex = strpos($qualifiedName, ":");
|
||
|
|
|
||
|
|
if ($colonIndex !== false) {
|
||
|
|
$node->prefix = substr($qualifiedName, 0, $colonIndex);
|
||
|
|
$node->localName = substr($qualifiedName, ($colonIndex + 1));
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$node->prefix = '';
|
||
|
|
$node->localName = $qualifiedName;
|
||
|
|
}
|
||
|
|
|
||
|
|
$node->namespaceURI = $namespaceURI;
|
||
|
|
|
||
|
|
$node->ownerDocument =& $this;
|
||
|
|
|
||
|
|
return $node;
|
||
|
|
} //createElementNS
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Creates a new DOMIT_Text node
|
||
|
|
* @param string The text of the node
|
||
|
|
* @return Object The new text node
|
||
|
|
*/
|
||
|
|
function &createTextNode($data) {
|
||
|
|
$node = new DOMIT_TextNode($data);
|
||
|
|
$node->ownerDocument =& $this;
|
||
|
|
|
||
|
|
return $node;
|
||
|
|
} //createTextNode
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Creates a new DOMIT_CDataSection node
|
||
|
|
* @param string The text of the CDATASection
|
||
|
|
* @return Object The new CDATASection node
|
||
|
|
*/
|
||
|
|
function &createCDATASection($data) {
|
||
|
|
$node = new DOMIT_CDATASection($data);
|
||
|
|
$node->ownerDocument =& $this;
|
||
|
|
|
||
|
|
return $node;
|
||
|
|
} //createCDATASection
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Creates a new DOMIT_Comment node
|
||
|
|
* @param string The comment text
|
||
|
|
* @return Object The new comment node
|
||
|
|
*/
|
||
|
|
function &createComment($text) {
|
||
|
|
$node = new DOMIT_Comment($text);
|
||
|
|
$node->ownerDocument =& $this;
|
||
|
|
|
||
|
|
return $node;
|
||
|
|
} //createComment
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Creates a new DOMIT_ProcessingInstruction node
|
||
|
|
* @param string The target of the processing instruction
|
||
|
|
* @param string The data of the processing instruction
|
||
|
|
* @return Object The new processing instruction node
|
||
|
|
*/
|
||
|
|
function &createProcessingInstruction($target, $data) {
|
||
|
|
$node = new DOMIT_ProcessingInstruction($target, $data);
|
||
|
|
$node->ownerDocument =& $this;
|
||
|
|
|
||
|
|
return $node;
|
||
|
|
} //createProcessingInstruction
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Retrieves a NodeList of child elements with the specified tag name
|
||
|
|
* @param string The matching element tag name
|
||
|
|
* @return Object A NodeList of found elements
|
||
|
|
*/
|
||
|
|
function &getElementsByTagName($tagName) {
|
||
|
|
$nodeList = new DOMIT_NodeList();
|
||
|
|
|
||
|
|
if ($this->documentElement != null) {
|
||
|
|
$this->documentElement->getNamedElements($nodeList, $tagName);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $nodeList;
|
||
|
|
} //getElementsByTagName
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Retrieves a NodeList of child elements with the specified namespaceURI and localName
|
||
|
|
* @param string The matching namespaceURI
|
||
|
|
* @param string The matching localName
|
||
|
|
* @return Object A NodeList of found elements
|
||
|
|
*/
|
||
|
|
function &getElementsByTagNameNS($namespaceURI, $localName) {
|
||
|
|
$nodeList = new DOMIT_NodeList();
|
||
|
|
|
||
|
|
if ($this->documentElement != null) {
|
||
|
|
$this->documentElement->getNamedElementsNS($nodeList, $namespaceURI, $localName);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $nodeList;
|
||
|
|
} //getElementsByTagNameNS
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the element whose ID is given by elementId.
|
||
|
|
* @param string The id of the matching element
|
||
|
|
* @param boolean True if XML spec is to be strictly adhered to (only attributes xml:id are considered valid)
|
||
|
|
* @return Object The found element or null
|
||
|
|
*/
|
||
|
|
function &getElementByID($elementID, $isStrict = true) {
|
||
|
|
if ($this->isNamespaceAware) {
|
||
|
|
if ($this->documentElement != null) {
|
||
|
|
$targetAttrNode =& $this->documentElement->_getElementByID($elementID, $isStrict);
|
||
|
|
return $targetAttrNode->ownerElement;
|
||
|
|
}
|
||
|
|
|
||
|
|
$null = null;
|
||
|
|
return $null;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_INVALID_ACCESS_ERR,
|
||
|
|
'Namespace awareness must be enabled to use method getElementByID');
|
||
|
|
}
|
||
|
|
} //getElementByID
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Retrieves an element or DOMIT_NodeList of elements corresponding to an Xpath-like expression.
|
||
|
|
* @param string The query pattern
|
||
|
|
* @param int If a single node is to be returned (rather than the entire NodeList) the index of that node
|
||
|
|
* @return mixed A NodeList or single node that matches the pattern
|
||
|
|
*/
|
||
|
|
function &getElementsByPath($pattern, $nodeIndex = 0) {
|
||
|
|
require_once(DOMIT_INCLUDE_PATH . 'xml_domit_getelementsbypath.php');
|
||
|
|
|
||
|
|
$gebp = new DOMIT_GetElementsByPath();
|
||
|
|
$myResponse =& $gebp->parsePattern($this, $pattern, $nodeIndex);
|
||
|
|
|
||
|
|
return $myResponse;
|
||
|
|
} //getElementsByPath
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Retrieves an element or DOMIT_NodeList of elements corresponding to an Xpath-like attribute expression (NOT YET IMPLEMENTED!)
|
||
|
|
* @param string The query pattern
|
||
|
|
* @param int If a single node is to be returned (rather than the entire NodeList) the index of that node
|
||
|
|
* @return mixed A NodeList or single node that matches the pattern
|
||
|
|
*/
|
||
|
|
function &getElementsByAttributePath($pattern, $nodeIndex = 0) {
|
||
|
|
require_once(DOMIT_INCLUDE_PATH . 'xml_domit_getelementsbypath.php');
|
||
|
|
|
||
|
|
$gabp = new DOMIT_GetElementsByAttributePath();
|
||
|
|
$myResponse =& $gabp->parsePattern($this, $pattern, $nodeIndex);
|
||
|
|
|
||
|
|
return $myResponse;
|
||
|
|
} //getElementsByAttributePath
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Retrieves all child nodes of the specified nodeType
|
||
|
|
* @param string The nodeType of matching nodes
|
||
|
|
* @param Object The root node of the search
|
||
|
|
* @return Object A NodeList containing found nodes
|
||
|
|
*/
|
||
|
|
function &getNodesByNodeType($type, &$contextNode) {
|
||
|
|
$nodeList = new DOMIT_NodeList();
|
||
|
|
|
||
|
|
if (($type == DOMIT_DOCUMENT_NODE) || ($contextNode->nodeType == DOMIT_DOCUMENT_NODE)){
|
||
|
|
$nodeList->appendNode($this);
|
||
|
|
}
|
||
|
|
else if ($contextNode->nodeType == DOMIT_ELEMENT_NODE) {
|
||
|
|
$contextNode->getTypedNodes($nodeList, $type);
|
||
|
|
}
|
||
|
|
else if ($contextNode->uid == $this->uid) {
|
||
|
|
if ($this->documentElement != null) {
|
||
|
|
if ($type == DOMIT_ELEMENT_NODE) {
|
||
|
|
$nodeList->appendNode($this->documentElement);
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->documentElement->getTypedNodes($nodeList, $type);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return $nodeList;
|
||
|
|
} //getNodesByNodeType
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Retrieves all child nodes of the specified nodeValue
|
||
|
|
* @param string The nodeValue of matching nodes
|
||
|
|
* @param Object The root node of the search
|
||
|
|
* @return Object A NodeList containing found nodes
|
||
|
|
*/
|
||
|
|
function &getNodesByNodeValue($value, &$contextNode) {
|
||
|
|
$nodeList = new DOMIT_NodeList();
|
||
|
|
|
||
|
|
if ($contextNode->uid == $this->uid) {
|
||
|
|
if ($this->nodeValue == $value) {
|
||
|
|
$nodeList->appendNode($this);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($this->documentElement != null) {
|
||
|
|
$this->documentElement->getValuedNodes($nodeList, $value);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $nodeList;
|
||
|
|
} //getNodesByNodeValue
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Parses an xml string
|
||
|
|
* @param string The xml text to be parsed
|
||
|
|
* @param boolean True if SAXY is to be used instead of Expat
|
||
|
|
* @param boolean False if CDATA Section are to be generated as Text nodes
|
||
|
|
* @param boolean True if onLoad is to be called on each node after parsing
|
||
|
|
* @return boolean True if parsing is successful
|
||
|
|
*/
|
||
|
|
function parseXML($xmlText, $useSAXY = true, $preserveCDATA = true, $fireLoadEvent = false) {
|
||
|
|
require_once(DOMIT_INCLUDE_PATH . 'xml_domit_utilities.php');
|
||
|
|
|
||
|
|
if ($this->doResolveErrors) {
|
||
|
|
require_once(DOMIT_INCLUDE_PATH . 'xml_domit_doctor.php');
|
||
|
|
$xmlText = DOMIT_Doctor::fixAmpersands($xmlText);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (DOMIT_Utilities::validateXML($xmlText)) {
|
||
|
|
$domParser = new DOMIT_Parser();
|
||
|
|
|
||
|
|
if ($useSAXY || (!function_exists('xml_parser_create'))) {
|
||
|
|
//use SAXY parser to populate xml tree
|
||
|
|
$this->parser = 'SAXY';
|
||
|
|
$success = $domParser->parseSAXY($this, $xmlText, $preserveCDATA, $this->definedEntities);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
//use Expat parser to populate xml tree
|
||
|
|
$this->parser = 'EXPAT';
|
||
|
|
$success = $domParser->parse($this, $xmlText, $preserveCDATA);
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($fireLoadEvent && ($this->documentElement != null)) $this->load($this->documentElement);
|
||
|
|
|
||
|
|
return $success;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
} //parseXML
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Parses an xml file
|
||
|
|
* @param string The xml file to be parsed
|
||
|
|
* @param boolean True if SAXY is to be used instead of Expat
|
||
|
|
* @param boolean False if CDATA Section are to be generated as Text nodes
|
||
|
|
* @param boolean True if onLoad is to be called on each node after parsing
|
||
|
|
* @return boolean True if parsing is successful
|
||
|
|
*/
|
||
|
|
function loadXML($filename, $useSAXY = true, $preserveCDATA = true, $fireLoadEvent = false) {
|
||
|
|
$xmlText = $this->getTextFromFile($filename);
|
||
|
|
|
||
|
|
return $this->parseXML($xmlText, $useSAXY, $preserveCDATA, $fireLoadEvent);
|
||
|
|
} //loadXML
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Establishes a connection, given an url
|
||
|
|
* @param string The url of the data
|
||
|
|
*/
|
||
|
|
function establishConnection($url) {
|
||
|
|
require_once(DOMIT_INCLUDE_PATH . 'php_http_client_generic.php');
|
||
|
|
|
||
|
|
$host = php_http_connection::formatHost($url);
|
||
|
|
$host = substr($host, 0, strpos($host, '/'));
|
||
|
|
|
||
|
|
$this->setConnection($host);
|
||
|
|
} //establishConnection
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Retrieves text from a file
|
||
|
|
* @param string The file path
|
||
|
|
* @return string The text contained in the file
|
||
|
|
*/
|
||
|
|
function getTextFromFile($filename) {
|
||
|
|
if ($this->doUseHTTPClient && (substr($filename, 0, 5) == 'http:')) {
|
||
|
|
$this->establishConnection($filename);
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($this->httpConnection != null) {
|
||
|
|
$response =& $this->httpConnection->get($filename);
|
||
|
|
|
||
|
|
$this->httpConnection->disconnect();
|
||
|
|
return $response->getResponse();
|
||
|
|
}
|
||
|
|
else if (function_exists('file_get_contents')) {
|
||
|
|
//if (file_exists($filename)) {
|
||
|
|
return file_get_contents($filename);
|
||
|
|
//}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
require_once(DOMIT_INCLUDE_PATH . 'php_file_utilities.php');
|
||
|
|
|
||
|
|
$fileContents =& php_file_utilities::getDataFromFile($filename, 'r');
|
||
|
|
return $fileContents;
|
||
|
|
}
|
||
|
|
|
||
|
|
return '';
|
||
|
|
} //getTextFromFile
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Saves the current DOM document as an xml file
|
||
|
|
* @param string The path of the xml file
|
||
|
|
* @param boolean True if xml text is to be normalized before saving
|
||
|
|
* @return boolean True if save is successful
|
||
|
|
*/
|
||
|
|
function saveXML($filename, $normalized = false) {
|
||
|
|
if ($normalized) {
|
||
|
|
$stringRep = $this->toNormalizedString(false, true);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$stringRep = $this->toString(false, true);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $this->saveTextToFile($filename, $stringRep);
|
||
|
|
} //saveXML
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Saves text to a file
|
||
|
|
* @param string The file path
|
||
|
|
* @param string The text to be saved
|
||
|
|
* @return boolean True if the save is successful
|
||
|
|
*/
|
||
|
|
function saveTextToFile($filename, $text) {
|
||
|
|
if (function_exists('file_put_contents')) {
|
||
|
|
file_put_contents($filename, $text);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
require_once(DOMIT_INCLUDE_PATH . 'php_file_utilities.php');
|
||
|
|
php_file_utilities::putDataToFile($filename, $text, 'w');
|
||
|
|
}
|
||
|
|
|
||
|
|
return (file_exists($filename) && is_writable($filename));
|
||
|
|
} //saveTextToFile
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Indicates the SAX parser used to parse the current document
|
||
|
|
* @return string Either "SAXY" or "EXPAT"
|
||
|
|
*/
|
||
|
|
function parsedBy() {
|
||
|
|
return $this->parser;
|
||
|
|
} //parsedBy
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the concatented text of the current node and its children
|
||
|
|
* @return string The concatented text of the current node and its children
|
||
|
|
*/
|
||
|
|
function getText() {
|
||
|
|
if ($this->documentElement != null) {
|
||
|
|
$root =& $this->documentElement;
|
||
|
|
return $root->getText();
|
||
|
|
}
|
||
|
|
|
||
|
|
return '';
|
||
|
|
} //getText
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns a doctype object
|
||
|
|
* @return mixed The doctype object, or null if none exists
|
||
|
|
*/
|
||
|
|
function getDocType() {
|
||
|
|
return $this->doctype;
|
||
|
|
} //getDocType
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the xml declaration processing instruction
|
||
|
|
* @return mixed The xml declaration processing instruction, or null if none exists
|
||
|
|
*/
|
||
|
|
function getXMLDeclaration() {
|
||
|
|
return $this->xmlDeclaration;
|
||
|
|
} //getXMLDeclaration
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns a reference to the DOMIT_DOMImplementation object
|
||
|
|
* @return Object A reference to the DOMIT_DOMImplementation object
|
||
|
|
*/
|
||
|
|
function &getDOMImplementation() {
|
||
|
|
return $this->implementation;
|
||
|
|
} //getDOMImplementation
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Manages the firing of the onLoad() event
|
||
|
|
* @param Object The parent node of the current recursion
|
||
|
|
*/
|
||
|
|
function load(&$contextNode) {
|
||
|
|
$total = $contextNode->childCount;
|
||
|
|
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
$currNode =& $contextNode->childNodes[$i];
|
||
|
|
$currNode->ownerDocument->load($currNode);
|
||
|
|
}
|
||
|
|
|
||
|
|
$contextNode->onLoad();
|
||
|
|
} //load
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the current version of DOMIT!
|
||
|
|
* @return Object The current version of DOMIT!
|
||
|
|
*/
|
||
|
|
function getVersion() {
|
||
|
|
return DOMIT_VERSION;
|
||
|
|
} //getVersion
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Appends an array of entity mappings to the existing translation table
|
||
|
|
*
|
||
|
|
* Intended mainly to facilitate the conversion of non-ASCII entities into equivalent characters
|
||
|
|
*
|
||
|
|
* @param array A list of entity mappings in the format: array('&' => '&');
|
||
|
|
*/
|
||
|
|
function appendEntityTranslationTable($table) {
|
||
|
|
$this->definedEntities = $table;
|
||
|
|
|
||
|
|
global $DOMIT_defined_entities_flip;
|
||
|
|
$DOMIT_defined_entities_flip = array_flip($table);
|
||
|
|
} //appendEntityTranslationTable
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates an array representation of the node and its children
|
||
|
|
* @return Array A representation of the node and its children
|
||
|
|
*/
|
||
|
|
function toArray() {
|
||
|
|
$arReturn = array($this->nodeName => array());
|
||
|
|
$total = $this->childCount;
|
||
|
|
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
$arReturn[$this->nodeName][$i] = $this->childNodes[$i]->toArray();
|
||
|
|
}
|
||
|
|
|
||
|
|
return $arReturn;
|
||
|
|
} //toArray
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Copies a node and/or its children
|
||
|
|
* @param boolean True if all child nodes are also to be cloned
|
||
|
|
* @return Object A copy of the node and/or its children
|
||
|
|
*/
|
||
|
|
function &cloneNode($deep = false) {
|
||
|
|
$className = get_class($this);
|
||
|
|
$clone = new $className($this->nodeName);
|
||
|
|
|
||
|
|
if ($deep) {
|
||
|
|
$total = $this->childCount;
|
||
|
|
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
$currentChild =& $this->childNodes[$i];
|
||
|
|
$clone->appendChild($currentChild->cloneNode($deep));
|
||
|
|
|
||
|
|
if ($currentChild->nodeType == DOMIT_DOCUMENT_TYPE_NODE) {
|
||
|
|
$clone->doctype =& $clone->childNodes[$i];
|
||
|
|
}
|
||
|
|
|
||
|
|
if (($currentChild->nodeType == DOMIT_PROCESSING_INSTRUCTION_NODE) &&
|
||
|
|
($currentChild->getTarget() == 'xml')) {
|
||
|
|
$clone->xmlDeclaration =& $clone->childNodes[$i];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return $clone;
|
||
|
|
} //cloneNode
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates a string representation of the node and its children
|
||
|
|
* @param boolean True if HTML readable output is desired
|
||
|
|
* @param boolean True if illegal xml characters in text nodes and attributes should be converted to entities
|
||
|
|
* @return string The string representation
|
||
|
|
*/
|
||
|
|
function toString($htmlSafe = false, $subEntities = false) {
|
||
|
|
$result = '';
|
||
|
|
$total = $this->childCount;
|
||
|
|
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
$result .= $this->childNodes[$i]->toString(false, $subEntities);
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($htmlSafe) $result = $this->forHTML($result);
|
||
|
|
|
||
|
|
return $result;
|
||
|
|
} //toString
|
||
|
|
} //DOMIT_Document
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A class representing the DOM Element
|
||
|
|
*
|
||
|
|
* @package domit-xmlparser
|
||
|
|
* @subpackage domit-xmlparser-main
|
||
|
|
* @author John Heinstein <johnkarl@nbnet.nb.ca>
|
||
|
|
*/
|
||
|
|
class DOMIT_Element extends DOMIT_ChildNodes_Interface {
|
||
|
|
/** @var array An array of namespacesURIs mapped to prefixes */
|
||
|
|
var $namespaceURIMap = array();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* DOM Element constructor
|
||
|
|
* @param string The tag name of the element
|
||
|
|
*/
|
||
|
|
function DOMIT_Element($tagName) {
|
||
|
|
$this->_constructor();
|
||
|
|
$this->nodeType = DOMIT_ELEMENT_NODE;
|
||
|
|
$this->nodeName = $tagName;
|
||
|
|
$this->attributes = new DOMIT_NamedNodeMap_Attr();
|
||
|
|
$this->childNodes = array();
|
||
|
|
} //DOMIT_Element
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the tag name of the element
|
||
|
|
* @return string The tag name of the element
|
||
|
|
*/
|
||
|
|
function getTagName() {
|
||
|
|
return $this->nodeName;
|
||
|
|
} //getTagName
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Adds elements with the specified tag name to a NodeList collection
|
||
|
|
* @param Object The NodeList collection
|
||
|
|
* @param string The tag name of matching elements
|
||
|
|
*/
|
||
|
|
function getNamedElements(&$nodeList, $tagName) {
|
||
|
|
if (($this->nodeName == $tagName) || ($tagName == '*')) {
|
||
|
|
$nodeList->appendNode($this);
|
||
|
|
}
|
||
|
|
|
||
|
|
$total = $this->childCount;
|
||
|
|
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
$this->childNodes[$i]->getNamedElements($nodeList, $tagName);
|
||
|
|
}
|
||
|
|
} //getNamedElements
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Creates an xmlns declaration at the current element
|
||
|
|
* @param array An array of namespace declarations in the scope of the current element
|
||
|
|
*/
|
||
|
|
function declareNamespace($localname, $value) {
|
||
|
|
//namespace URI for xmlns attribute is: http://www.w3.org/2000/xmlns/
|
||
|
|
$this->setAttributeNS(DOMIT_XMLNS_NAMESPACE, ('xmlns:' . $localname), $value);
|
||
|
|
|
||
|
|
//add to local namespaceURI map
|
||
|
|
$this->namespaceURIMap[$value] = $localname;
|
||
|
|
} //declareNamespace
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Creates a default xmlns declaration at the current element
|
||
|
|
* @param array An array of namespace declarations in the scope of the current element
|
||
|
|
*/
|
||
|
|
function declareDefaultNamespace($value) {
|
||
|
|
//namespace URI for xmlns attribute is: http://www.w3.org/2000/xmlns/
|
||
|
|
$this->setAttributeNS(DOMIT_XMLNS_NAMESPACE, 'xmlns', $value);
|
||
|
|
|
||
|
|
//add to local namespaceURI map
|
||
|
|
$this->namespaceURIMap[$value] = 'xmlns';
|
||
|
|
} //declareDefaultNamespace
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns an array of namespace declarations in the scope of the current element
|
||
|
|
* @return array An array of namespace declarations in the scope of the current element
|
||
|
|
*/
|
||
|
|
function &getNamespaceDeclarationsInScope() {
|
||
|
|
$nsMap = array();
|
||
|
|
|
||
|
|
return $this->_getNameSpaceDeclarationsInScope($nsMap);
|
||
|
|
} //getNamespacesInScope
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns an array of namespace declarations in the scope of the current element
|
||
|
|
* @return array An array of namespace declarations in the scope of the current element
|
||
|
|
*/
|
||
|
|
function &_getNamespaceDeclarationsInScope(&$nsMap) {
|
||
|
|
//grab local xmlns declarations if not already present
|
||
|
|
foreach ($this->namespaceURIMap as $key => $value) {
|
||
|
|
if (!isset($nsMap[$key])) {
|
||
|
|
$nsMap[$key] = $value;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//move up the tree if not already at the top
|
||
|
|
if ($this->parentNode->uid != $this->ownerDocument->uid) {
|
||
|
|
$this->parentNode->_getNamespaceDeclarationsInScope($nsMap);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $nsMap;
|
||
|
|
} //_getNamespacesInScope
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the default xmlns declaration for the current element
|
||
|
|
* @return string The default xmlns declaration for the current element
|
||
|
|
*/
|
||
|
|
function getDefaultNamespaceDeclaration() {
|
||
|
|
if (in_array('xmlns', $this->namespaceURIMap)) {
|
||
|
|
foreach ($this->namespaceURIMap as $key => $value) {
|
||
|
|
if ($value == 'xmlns') {
|
||
|
|
return $key;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if ($this->parentNode->uid != $this->ownerDocument->uid) {
|
||
|
|
return $this->parentNode->getDefaultNamespaceDeclaration();
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
return '';
|
||
|
|
}
|
||
|
|
} //getDefaultNamespaceDeclaration
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Copies all namespace declarations in scope to the namespace URI map of the current element
|
||
|
|
*/
|
||
|
|
function copyNamespaceDeclarationsLocally() {
|
||
|
|
$nsMap = $this->getNamespaceDeclarationsInScope();
|
||
|
|
|
||
|
|
//add xmlns declarations as attributes
|
||
|
|
foreach ($nsMap as $key => $value) {
|
||
|
|
if ($value == 'xmlns') {
|
||
|
|
$this->declareDefaultNamespace($key);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$this->declareNamespace($value, $key);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} //copyNamespaceDeclarationsLocally
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Adds elements with the specified tag name to a NodeList collection
|
||
|
|
* @param Object The NodeList collection
|
||
|
|
* @param string The namespaceURI of matching elements
|
||
|
|
* @param string The localName of matching elements
|
||
|
|
*/
|
||
|
|
function getNamedElementsNS(&$nodeList, $namespaceURI, $localName) {
|
||
|
|
if ((($namespaceURI == $this->namespaceURI) || ($namespaceURI == '*')) &&
|
||
|
|
(($localName == $this->localName) || ($localName == '*'))) {
|
||
|
|
$nodeList->appendNode($this);
|
||
|
|
}
|
||
|
|
|
||
|
|
$total = $this->childCount;
|
||
|
|
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
if ($this->childNodes[$i]->nodeType == DOMIT_ELEMENT_NODE) {
|
||
|
|
$this->childNodes[$i]->getNamedElementsNS($nodeList, $namespaceURI, $localName);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} //getNamedElementsNS
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the concatented text of the current node and its children
|
||
|
|
* @return string The concatented text of the current node and its children
|
||
|
|
*/
|
||
|
|
function getText() {
|
||
|
|
$text = '';
|
||
|
|
$numChildren = $this->childCount;
|
||
|
|
|
||
|
|
for ($i = 0; $i < $numChildren; $i++) {
|
||
|
|
$child =& $this->childNodes[$i];
|
||
|
|
$text .= $child->getText();
|
||
|
|
}
|
||
|
|
|
||
|
|
return $text;
|
||
|
|
} //getText
|
||
|
|
|
||
|
|
/**
|
||
|
|
* If a child text node exists, sets the nodeValue to $data. A child text node is created if none exists
|
||
|
|
* @param string The text data of the node
|
||
|
|
*/
|
||
|
|
function setText($data) {
|
||
|
|
switch ($this->childCount) {
|
||
|
|
case 1:
|
||
|
|
if ($this->firstChild->nodeType == DOMIT_TEXT_NODE) {
|
||
|
|
$this->firstChild->setText($data);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case 0:
|
||
|
|
$childTextNode =& $this->ownerDocument->createTextNode($data);
|
||
|
|
$this->appendChild($childTextNode);
|
||
|
|
break;
|
||
|
|
|
||
|
|
default:
|
||
|
|
//do nothing. Maybe throw error???
|
||
|
|
}
|
||
|
|
} //setText
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Retrieves a NodeList of child elements with the specified tag name
|
||
|
|
* @param string The matching element tag name
|
||
|
|
* @return Object A NodeList of found elements
|
||
|
|
*/
|
||
|
|
function &getElementsByTagName($tagName) {
|
||
|
|
$nodeList = new DOMIT_NodeList();
|
||
|
|
$this->getNamedElements($nodeList, $tagName);
|
||
|
|
|
||
|
|
return $nodeList;
|
||
|
|
} //getElementsByTagName
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Retrieves a NodeList of child elements with the specified namespaceURI and localName
|
||
|
|
* @param string The namespaceURI
|
||
|
|
* @param string The localName
|
||
|
|
* @return Object A NodeList of found elements
|
||
|
|
*/
|
||
|
|
function &getElementsByTagNameNS($namespaceURI, $localName) {
|
||
|
|
$nodeList = new DOMIT_NodeList();
|
||
|
|
$this->getNamedElementsNS($nodeList, $namespaceURI, $localName);
|
||
|
|
|
||
|
|
return $nodeList;
|
||
|
|
} //getElementsByTagNameNS
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the attribute node whose ID is given by elementId.
|
||
|
|
* @param string The id of the matching element
|
||
|
|
* @param boolean True if XML spec is to be strictly adhered to (only attributes xml:id are considered valid)
|
||
|
|
* @return Object The found attribute or null
|
||
|
|
*/
|
||
|
|
function &_getElementByID($elementID, $isStrict) {
|
||
|
|
if ($isStrict) {
|
||
|
|
$myAttrNode =& $this->getAttributeNodeNS(DOMIT_XML_NAMESPACE, 'id');
|
||
|
|
if (($myAttrNode != null)&& ($myAttrNode->getValue() == $elementID)) return $myAttrNode;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$myAttrNode =& $this->getAttributeNodeNS('', 'ID');
|
||
|
|
if (($myAttrNode != null)&& ($myAttrNode->getValue() == $elementID)) return $myAttrNode;
|
||
|
|
|
||
|
|
$myAttrNode =& $this->getAttributeNodeNS('', 'id');
|
||
|
|
if (($myAttrNode != null)&& ($myAttrNode->getValue() == $elementID)) return $myAttrNode;
|
||
|
|
}
|
||
|
|
|
||
|
|
$total = $this->childCount;
|
||
|
|
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
if ($this->childNodes[$i]->nodeType == DOMIT_ELEMENT_NODE) {
|
||
|
|
$foundNode =& $this->childNodes[$i]->_getElementByID($elementID, $isStrict);
|
||
|
|
|
||
|
|
if ($foundNode != null) {
|
||
|
|
return $foundNode;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$null = null;
|
||
|
|
return $null;
|
||
|
|
} //_getElementByID
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Retrieves an element or DOMIT_NodeList of elements corresponding to an Xpath-like expression.
|
||
|
|
* @param string The query pattern
|
||
|
|
* @param int If a single node is to be returned (rather than the entire NodeList) the index of that node
|
||
|
|
* @return mixed A NodeList or single node that matches the pattern
|
||
|
|
*/
|
||
|
|
function &getElementsByPath($pattern, $nodeIndex = 0) {
|
||
|
|
require_once(DOMIT_INCLUDE_PATH . 'xml_domit_getelementsbypath.php');
|
||
|
|
|
||
|
|
$gebp = new DOMIT_GetElementsByPath();
|
||
|
|
$myResponse =& $gebp->parsePattern($this, $pattern, $nodeIndex);
|
||
|
|
|
||
|
|
return $myResponse;
|
||
|
|
} //getElementsByPath
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Retrieves an element or DOMIT_NodeList of elements corresponding to an Xpath-like attribute expression (NOT YET IMPLEMENTED!)
|
||
|
|
* @param string The query pattern
|
||
|
|
* @param int If a single node is to be returned (rather than the entire NodeList) the index of that node
|
||
|
|
* @return mixed A NodeList or single node that matches the pattern
|
||
|
|
*/
|
||
|
|
function &getElementsByAttributePath($pattern, $nodeIndex = 0) {
|
||
|
|
require_once(DOMIT_INCLUDE_PATH . 'xml_domit_getelementsbypath.php');
|
||
|
|
|
||
|
|
$gabp = new DOMIT_GetElementsByAttributePath();
|
||
|
|
$myResponse =& $gabp->parsePattern($this, $pattern, $nodeIndex);
|
||
|
|
|
||
|
|
return $myResponse;
|
||
|
|
} //getElementsByAttributePath
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Adds all child nodes of the specified nodeType to the NodeList
|
||
|
|
* @param Object The NodeList collection
|
||
|
|
* @param string The nodeType of matching nodes
|
||
|
|
*/
|
||
|
|
function getTypedNodes(&$nodeList, $type) {
|
||
|
|
$numChildren = $this->childCount;
|
||
|
|
|
||
|
|
for ($i = 0; $i < $numChildren; $i++) {
|
||
|
|
$child =& $this->childNodes[$i];
|
||
|
|
|
||
|
|
if ($child->nodeType == $type) {
|
||
|
|
$nodeList->appendNode($child);
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($child->hasChildNodes()) {
|
||
|
|
$child->getTypedNodes($nodeList, $type);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} //getTypedNodes
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Adds all child nodes of the specified nodeValue to the NodeList
|
||
|
|
* @param Object The NodeList collection
|
||
|
|
* @param string The nodeValue of matching nodes
|
||
|
|
*/
|
||
|
|
function getValuedNodes(&$nodeList, $value) {
|
||
|
|
$numChildren = $this->childCount;
|
||
|
|
|
||
|
|
for ($i = 0; $i < $numChildren; $i++) {
|
||
|
|
$child =& $this->childNodes[$i];
|
||
|
|
|
||
|
|
if ($child->nodeValue == $value) {
|
||
|
|
$nodeList->appendNode($child);
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($child->hasChildNodes()) {
|
||
|
|
$child->getValuedNodes($nodeList, $value);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} //getValuedNodes
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Gets the value of the specified attribute, if it exists
|
||
|
|
* @param string The attribute name
|
||
|
|
* @return string The attribute value
|
||
|
|
*/
|
||
|
|
function getAttribute($name) {
|
||
|
|
$returnNode =& $this->attributes->getNamedItem($name);
|
||
|
|
|
||
|
|
if ($returnNode == null) {
|
||
|
|
return '';
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
return $returnNode->getValue();
|
||
|
|
}
|
||
|
|
} //getAttribute
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Gets the value of the attribute with the specified namespaceURI and localName, if it exists
|
||
|
|
* @param string The namespaceURI
|
||
|
|
* @param string The localName
|
||
|
|
* @return string The attribute value
|
||
|
|
*/
|
||
|
|
function getAttributeNS($namespaceURI, $localName) {
|
||
|
|
$returnNode =& $this->attributes->getNamedItemNS($namespaceURI, $localName);
|
||
|
|
|
||
|
|
if ($returnNode == null) {
|
||
|
|
return '';
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
return $returnNode->getValue();
|
||
|
|
}
|
||
|
|
} //getAttributeNS
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Sets the value of the specified attribute; creates a new attribute if one doesn't exist
|
||
|
|
* @param string The attribute name
|
||
|
|
* @param string The desired attribute value
|
||
|
|
*/
|
||
|
|
function setAttribute($name, $value) {
|
||
|
|
$returnNode =& $this->attributes->getNamedItem($name);
|
||
|
|
|
||
|
|
if ($returnNode == null) {
|
||
|
|
$newAttr = new DOMIT_Attr($name);
|
||
|
|
$newAttr->setValue($value);
|
||
|
|
$this->attributes->setNamedItem($newAttr);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$returnNode->setValue($value);
|
||
|
|
}
|
||
|
|
} //setAttribute
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Sets the value of the specified attribute; creates a new attribute if one doesn't exist
|
||
|
|
* @param string The attribute namespaceURI
|
||
|
|
* @param string The attribute qualifiedName
|
||
|
|
* @param string The desired attribute value
|
||
|
|
*/
|
||
|
|
function setAttributeNS($namespaceURI, $qualifiedName, $value) {
|
||
|
|
//get localName
|
||
|
|
$colonIndex = strpos($qualifiedName, ":");
|
||
|
|
|
||
|
|
if ($colonIndex !== false) {
|
||
|
|
$localName = substr($qualifiedName, ($colonIndex + 1));
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$localName = $qualifiedName;
|
||
|
|
}
|
||
|
|
|
||
|
|
$returnNode =& $this->attributes->getNamedItemNS($namespaceURI, $localName);
|
||
|
|
|
||
|
|
if ($returnNode == null) {
|
||
|
|
//create this manually in case element has no ownerDocument to reference
|
||
|
|
$newAttr = new DOMIT_Attr($qualifiedName);
|
||
|
|
$newAttr->prefix = substr($qualifiedName, 0, $colonIndex);
|
||
|
|
$newAttr->localName = $localName;
|
||
|
|
$newAttr->namespaceURI = $namespaceURI;
|
||
|
|
|
||
|
|
$newAttr->setValue($value);
|
||
|
|
$this->attributes->setNamedItemNS($newAttr);
|
||
|
|
$newAttr->ownerElement =& $this;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$returnNode->setValue($value);
|
||
|
|
}
|
||
|
|
} //setAttributeNS
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Removes the specified attribute
|
||
|
|
* @param string The name of the attribute to be removed
|
||
|
|
*/
|
||
|
|
function removeAttribute($name) {
|
||
|
|
$returnNode =& $this->attributes->removeNamedItem($name);
|
||
|
|
} //removeAttribute
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Removes the specified attribute
|
||
|
|
* @param string The namespaceURI of the attribute to be removed
|
||
|
|
* @param string The localName of the attribute to be removed
|
||
|
|
*/
|
||
|
|
function removeAttributeNS($namespaceURI, $localName) {
|
||
|
|
$returnNode =& $this->attributes->removeNamedItemNS($namespaceURI, $localName);
|
||
|
|
unset($returnNode->ownerElement);
|
||
|
|
$returnNode->ownerElement = null;
|
||
|
|
} //removeAttributeNS
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Determines whether an attribute with the specified name exists
|
||
|
|
* @param string The name of the attribute
|
||
|
|
* @return boolean True if the attribute exists
|
||
|
|
*/
|
||
|
|
function hasAttribute($name) {
|
||
|
|
$returnNode =& $this->attributes->getNamedItem($name);
|
||
|
|
|
||
|
|
return ($returnNode != null);
|
||
|
|
} //hasAttribute
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Determines whether an attribute with the specified namespaceURI and localName exists
|
||
|
|
* @param string The namespaceURI of the attribute
|
||
|
|
* @param string The localName of the attribute
|
||
|
|
* @return boolean True if the attribute exists
|
||
|
|
*/
|
||
|
|
function hasAttributeNS($namespaceURI, $localName) {
|
||
|
|
$returnNode =& $this->attributes->getNamedItemNS($namespaceURI, $localName);
|
||
|
|
|
||
|
|
return ($returnNode != null);
|
||
|
|
} //hasAttributeNS
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Determines whether the element has any atributes
|
||
|
|
* @return boolean True if the element has any atributes
|
||
|
|
*/
|
||
|
|
function hasAttributes() {
|
||
|
|
return ($this->attributes->getLength() > 0);
|
||
|
|
} //hasChildNodes
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Gets a reference to the specified attribute node
|
||
|
|
* @param string The attribute name
|
||
|
|
* @return Object A reference to the found node, or null
|
||
|
|
*/
|
||
|
|
function &getAttributeNode($name) {
|
||
|
|
$returnNode =& $this->attributes->getNamedItem($name);
|
||
|
|
return $returnNode;
|
||
|
|
} //getAttributeNode
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Gets a reference to the specified attribute node
|
||
|
|
* @param string The attribute namespaceURI
|
||
|
|
* @param string The attribute localName
|
||
|
|
* @return Object A reference to the found node, or null
|
||
|
|
*/
|
||
|
|
function &getAttributeNodeNS($namespaceURI, $localName) {
|
||
|
|
$returnNode =& $this->attributes->getNamedItemNS($namespaceURI, $localName);
|
||
|
|
return $returnNode;
|
||
|
|
} //getAttributeNodeNS
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Adds an attribute node to the current element
|
||
|
|
* @param Object The attribute node to be added
|
||
|
|
* @return Object A reference to the newly added node
|
||
|
|
*/
|
||
|
|
function &setAttributeNode(&$newAttr) {
|
||
|
|
$returnNode =& $this->attributes->setNamedItem($newAttr);
|
||
|
|
return $returnNode;
|
||
|
|
} //setAttributeNode
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Adds an attribute node to the current element (namespace aware)
|
||
|
|
* @param Object The attribute node to be added
|
||
|
|
* @return Object A reference to the newly added node
|
||
|
|
*/
|
||
|
|
function &setAttributeNodeNS(&$newAttr) {
|
||
|
|
$returnNode =& $this->attributes->setNamedItemNS($newAttr);
|
||
|
|
$newAttr->ownerElement =& $this;
|
||
|
|
return $returnNode;
|
||
|
|
} //setAttributeNodeNS
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Removes an attribute node from the current element
|
||
|
|
* @param Object The attribute node to be removed
|
||
|
|
* @return Object A reference to the removed node
|
||
|
|
*/
|
||
|
|
function &removeAttributeNode(&$oldAttr) {
|
||
|
|
$attrName = $oldAttr->getName();
|
||
|
|
$returnNode =& $this->attributes->removeNamedItem($attrName);
|
||
|
|
|
||
|
|
if ($returnNode == null) {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_NOT_FOUND_ERR,
|
||
|
|
'Target attribute not found.');
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
return $returnNode;
|
||
|
|
}
|
||
|
|
} //removeAttributeNode
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Collapses adjacent text nodes in entire element subtree
|
||
|
|
*/
|
||
|
|
function normalize() {
|
||
|
|
if ($this->hasChildNodes()) {
|
||
|
|
$currNode =& $this->childNodes[0];
|
||
|
|
|
||
|
|
while ($currNode->nextSibling != null) {
|
||
|
|
$nextNode =& $currNode->nextSibling;
|
||
|
|
|
||
|
|
if (($currNode->nodeType == DOMIT_TEXT_NODE) &&
|
||
|
|
($nextNode->nodeType == DOMIT_TEXT_NODE)) {
|
||
|
|
|
||
|
|
$currNode->nodeValue .= $nextNode->nodeValue;
|
||
|
|
$this->removeChild($nextNode);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$currNode->normalize();
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($currNode->nextSibling != null) {
|
||
|
|
$currNode =& $currNode->nextSibling;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} //normalize
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates an array representation of the node and its children
|
||
|
|
* @return Array A representation of the node and its children
|
||
|
|
*/
|
||
|
|
function toArray() {
|
||
|
|
$arReturn = array($this->nodeName => array("attributes" => $this->attributes->toArray()));
|
||
|
|
$total = $this->childCount;
|
||
|
|
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
$arReturn[$this->nodeName][$i] = $this->childNodes[$i]->toArray();
|
||
|
|
}
|
||
|
|
|
||
|
|
return $arReturn;
|
||
|
|
} //toArray
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Copies a node and/or its children
|
||
|
|
* @param boolean True if all child nodes are also to be cloned
|
||
|
|
* @return Object A copy of the node and/or its children
|
||
|
|
*/
|
||
|
|
function &cloneNode($deep = false) {
|
||
|
|
$className = get_class($this);
|
||
|
|
$clone = new $className($this->nodeName);
|
||
|
|
|
||
|
|
$clone->attributes =& $this->attributes->createClone($deep);
|
||
|
|
|
||
|
|
if ($this->namespaceURI) {
|
||
|
|
$clone->namespaceURI = $this->namespaceURI;
|
||
|
|
$clone->localName = $this->localName;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($deep) {
|
||
|
|
$total = $this->childCount;
|
||
|
|
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
$currentChild =& $this->childNodes[$i];
|
||
|
|
$clone->appendChild($currentChild->cloneNode($deep));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return $clone;
|
||
|
|
} //cloneNode
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates a string representation of the node and its children
|
||
|
|
* @param boolean True if HTML readable output is desired
|
||
|
|
* @param boolean True if illegal xml characters in text nodes and attributes should be converted to entities
|
||
|
|
* @return string The string representation
|
||
|
|
*/
|
||
|
|
function toString($htmlSafe = false, $subEntities = false) {
|
||
|
|
$result = '<' . $this->nodeName;
|
||
|
|
$result .= $this->attributes->toString(false, $subEntities);
|
||
|
|
|
||
|
|
if ($this->ownerDocument->isNamespaceAware) {
|
||
|
|
foreach ($this->namespaceURIMap as $key => $value) {
|
||
|
|
$result .= ' xmlns:' . $value . '="' . $key . '"';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//get children
|
||
|
|
$myNodes =& $this->childNodes;
|
||
|
|
$total = count($myNodes);
|
||
|
|
|
||
|
|
if ($total != 0) {
|
||
|
|
$result .= '>';
|
||
|
|
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
$child =& $myNodes[$i];
|
||
|
|
$result .= $child->toString(false, $subEntities);
|
||
|
|
}
|
||
|
|
|
||
|
|
$result .= '</' . $this->nodeName . '>';
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if ($this->ownerDocument->doExpandEmptyElementTags) {
|
||
|
|
if (in_array($this->nodeName, $this->ownerDocument->expandEmptyElementExceptions)) {
|
||
|
|
$result .= ' />';
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$result .= '></' . $this->nodeName . '>';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (in_array($this->nodeName, $this->ownerDocument->expandEmptyElementExceptions)) {
|
||
|
|
$result .= '></' . $this->nodeName . '>';
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$result .= ' />';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($htmlSafe) $result = $this->forHTML($result);
|
||
|
|
|
||
|
|
return $result;
|
||
|
|
} //toString
|
||
|
|
} //DOMIT_Element
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A parent class for Text and CDATA Section nodes
|
||
|
|
*
|
||
|
|
* @package domit-xmlparser
|
||
|
|
* @subpackage domit-xmlparser-main
|
||
|
|
* @author John Heinstein <johnkarl@nbnet.nb.ca>
|
||
|
|
*/
|
||
|
|
class DOMIT_CharacterData extends DOMIT_Node {
|
||
|
|
/**
|
||
|
|
* Prevents direct instantiation of DOMIT_CharacterData class
|
||
|
|
* @abstract
|
||
|
|
*/
|
||
|
|
function DOMIT_CharacterData() {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_ABSTRACT_CLASS_INSTANTIATION_ERR,
|
||
|
|
'Cannot instantiate abstract class DOMIT_CharacterData');
|
||
|
|
} //DOMIT_CharacterData
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Gets the node value of the current text node
|
||
|
|
* @return string The node value of the current text node
|
||
|
|
*/
|
||
|
|
function getData() {
|
||
|
|
return $this->nodeValue;
|
||
|
|
} //getData
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Sets the text contained in the current node to $data.
|
||
|
|
* @param string The text data of the node
|
||
|
|
*/
|
||
|
|
function setData($data) {
|
||
|
|
$this->nodeValue = $data;
|
||
|
|
} //setData
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Gets the length of the text in the current node
|
||
|
|
* @return int The length of the text in the current node
|
||
|
|
*/
|
||
|
|
function getLength() {
|
||
|
|
return strlen($this->nodeValue);
|
||
|
|
} //getLength
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Gets a subset of the current node text
|
||
|
|
* @param int The starting point of the substring
|
||
|
|
* @param int The length of the substring
|
||
|
|
* @return string The subset of the current node text
|
||
|
|
*/
|
||
|
|
function substringData($offset, $count) {
|
||
|
|
$totalChars = $this->getLength();
|
||
|
|
|
||
|
|
if (($offset < 0) || (($offset + $count) > $totalChars)) {
|
||
|
|
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_INDEX_SIZE_ERR,
|
||
|
|
'Character Data index out of bounds.');
|
||
|
|
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$data = $this->getData();
|
||
|
|
return substr($data, $offset, $count);
|
||
|
|
}
|
||
|
|
} //substringData
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Appends the specified text to the current node text
|
||
|
|
* @param string The text to be appended
|
||
|
|
*/
|
||
|
|
function appendData($arg) {
|
||
|
|
$this->setData($this->getData() . $arg);
|
||
|
|
} //appendData
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Inserts text at the sepecified offset
|
||
|
|
* @param int The insertion point
|
||
|
|
* @param string The text to be inserted
|
||
|
|
*/
|
||
|
|
function insertData($offset, $arg) {
|
||
|
|
$totalChars = $this->getLength();
|
||
|
|
|
||
|
|
if (($offset < 0) || ($offset > $totalChars)) {
|
||
|
|
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_INDEX_SIZE_ERR,
|
||
|
|
'Character Data index out of bounds.');
|
||
|
|
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$data = $this->getData();
|
||
|
|
$pre = substr($data, 0, $offset);
|
||
|
|
$post = substr($data, $offset);
|
||
|
|
|
||
|
|
$this->setData(($pre . $arg . $post));
|
||
|
|
}
|
||
|
|
} //insertData
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Deletes a subset of the current node text
|
||
|
|
* @param int The starting point of the deletion
|
||
|
|
* @param int The length of the deletion
|
||
|
|
*/
|
||
|
|
function deleteData($offset, $count) {
|
||
|
|
$totalChars = $this->getLength();
|
||
|
|
|
||
|
|
if (($offset < 0) || (($offset + $count) > $totalChars)) {
|
||
|
|
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_INDEX_SIZE_ERR,
|
||
|
|
'Character Data index out of bounds.');
|
||
|
|
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$data = $this->getData();
|
||
|
|
$pre = substr($data, 0, $offset);
|
||
|
|
$post = substr($data, ($offset + $count));
|
||
|
|
|
||
|
|
$this->setData(($pre . $post));
|
||
|
|
}
|
||
|
|
} //substringData
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Replaces a subset of the current node text with the specified text
|
||
|
|
* @param int The starting point of the replacement
|
||
|
|
* @param int The length of the replacement
|
||
|
|
* @param string The replacement text
|
||
|
|
*/
|
||
|
|
function replaceData($offset, $count, $arg) {
|
||
|
|
$totalChars = $this->getLength();
|
||
|
|
|
||
|
|
if (($offset < 0) || (($offset + $count) > $totalChars)) {
|
||
|
|
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_INDEX_SIZE_ERR,
|
||
|
|
'Character Data index out of bounds.');
|
||
|
|
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$data = $this->getData();
|
||
|
|
$pre = substr($data, 0, $offset);
|
||
|
|
$post = substr($data, ($offset + $count));
|
||
|
|
|
||
|
|
$this->setData(($pre . $arg . $post));
|
||
|
|
}
|
||
|
|
} //replaceData
|
||
|
|
} //DOMIT_CharacterData
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A class representing the DOM Text Node
|
||
|
|
*
|
||
|
|
* @package domit-xmlparser
|
||
|
|
* @subpackage domit-xmlparser-main
|
||
|
|
* @author John Heinstein <johnkarl@nbnet.nb.ca>
|
||
|
|
*/
|
||
|
|
class DOMIT_TextNode extends DOMIT_CharacterData {
|
||
|
|
/**
|
||
|
|
* DOM Text Node constructor
|
||
|
|
* @param string The text of the node
|
||
|
|
*/
|
||
|
|
function DOMIT_TextNode($data) {
|
||
|
|
$this->_constructor();
|
||
|
|
$this->nodeType = DOMIT_TEXT_NODE;
|
||
|
|
$this->nodeName = '#text';
|
||
|
|
$this->setText($data);
|
||
|
|
} //DOMIT_TextNode
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the text contained in the current node
|
||
|
|
* @return string The text of the current node
|
||
|
|
*/
|
||
|
|
function getText() {
|
||
|
|
return $this->nodeValue;
|
||
|
|
} //getText
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Sets the text contained in the current node to $data.
|
||
|
|
* @param string The text data of the node
|
||
|
|
*/
|
||
|
|
function setText($data) {
|
||
|
|
$this->nodeValue = $data;
|
||
|
|
} //setText
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Splits a single node into multiple nodes, based on the specified offset
|
||
|
|
* @param int The offset point for the split
|
||
|
|
* @return Object The newly created text node
|
||
|
|
*/
|
||
|
|
function &splitText($offset) {
|
||
|
|
$totalChars = $this->getLength();
|
||
|
|
|
||
|
|
if (($offset < 0) || ($offset > $totalChars)) {
|
||
|
|
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_INDEX_SIZE_ERR,
|
||
|
|
'Character Data index out of bounds.');
|
||
|
|
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$data = $this->getData();
|
||
|
|
$pre = substr($data, 0, $offset);
|
||
|
|
$post = substr($data, $offset);
|
||
|
|
|
||
|
|
$this->setText($pre);
|
||
|
|
|
||
|
|
//create new text node
|
||
|
|
$className = get_class($this);
|
||
|
|
$newTextNode = new $className($post);
|
||
|
|
$newTextNode->ownerDocument =& $this->ownerDocument;
|
||
|
|
|
||
|
|
if ($this->parentNode->lastChild->uid == $this->uid) {
|
||
|
|
$this->parentNode->appendChild($newTextNode);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$this->parentNode->insertBefore($newTextNode, $this);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $newTextNode;
|
||
|
|
}
|
||
|
|
} //splitText
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates an array representation of the node and its children
|
||
|
|
* @return Array A representation of the node and its children
|
||
|
|
*/
|
||
|
|
function toArray() {
|
||
|
|
return $this->toString();
|
||
|
|
} //toArray
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Copies a node and/or its children
|
||
|
|
* @param boolean True if all child nodes are also to be cloned
|
||
|
|
* @return Object A copy of the node and/or its children
|
||
|
|
*/
|
||
|
|
function &cloneNode($deep = false) {
|
||
|
|
$className = get_class($this);
|
||
|
|
$clone = new $className($this->nodeValue);
|
||
|
|
|
||
|
|
return $clone;
|
||
|
|
} //cloneNode
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates a string representation of the node and its children
|
||
|
|
* @param boolean True if HTML readable output is desired
|
||
|
|
* @param boolean True if illegal xml characters should be converted to entities
|
||
|
|
* @return string The string representation
|
||
|
|
*/
|
||
|
|
function toString($htmlSafe = false, $subEntities = false) {
|
||
|
|
require_once(DOMIT_INCLUDE_PATH . 'xml_domit_utilities.php');
|
||
|
|
global $DOMIT_defined_entities_flip;
|
||
|
|
|
||
|
|
$result = $subEntities ? DOMIT_Utilities::convertEntities($this->nodeValue,
|
||
|
|
$DOMIT_defined_entities_flip) : $this->nodeValue;
|
||
|
|
|
||
|
|
if ($htmlSafe) $result = $this->forHTML($result);
|
||
|
|
|
||
|
|
return $result;
|
||
|
|
} //toString
|
||
|
|
} //DOMIT_TextNode
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A class representing the DOM CDATA Section
|
||
|
|
*
|
||
|
|
* @package domit-xmlparser
|
||
|
|
* @subpackage domit-xmlparser-main
|
||
|
|
* @author John Heinstein <johnkarl@nbnet.nb.ca>
|
||
|
|
*/
|
||
|
|
class DOMIT_CDATASection extends DOMIT_TextNode {
|
||
|
|
/**
|
||
|
|
* DOM CDATA Section node constructor
|
||
|
|
* @param string The text of the node
|
||
|
|
*/
|
||
|
|
function DOMIT_CDATASection($data) {
|
||
|
|
$this->_constructor();
|
||
|
|
$this->nodeType = DOMIT_CDATA_SECTION_NODE;
|
||
|
|
$this->nodeName = '#cdata-section';
|
||
|
|
$this->setText($data);
|
||
|
|
} //DOMIT_CDATASection
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates a string representation of the node and its children
|
||
|
|
* @param boolean True if HTML readable output is desired
|
||
|
|
* @param boolean True if illegal xml characters should be converted to entities
|
||
|
|
* @return string The string representation
|
||
|
|
*/
|
||
|
|
function toString($htmlSafe = false, $subEntities = false) {
|
||
|
|
$result = '<![CDATA[';
|
||
|
|
$result .= $subEntities ? str_replace("]]>", "]]>", $this->nodeValue) :
|
||
|
|
$this->nodeValue;
|
||
|
|
$result .= ']]>';
|
||
|
|
|
||
|
|
if ($htmlSafe) $result = $this->forHTML($result);
|
||
|
|
|
||
|
|
return $result;
|
||
|
|
} //toString
|
||
|
|
} //DOMIT_CDATASection
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A class representing the Attr node
|
||
|
|
*
|
||
|
|
* @package domit-xmlparser
|
||
|
|
* @subpackage domit-xmlparser-main
|
||
|
|
* @author John Heinstein <johnkarl@nbnet.nb.ca>
|
||
|
|
*/
|
||
|
|
class DOMIT_Attr extends DOMIT_Node {
|
||
|
|
/** @var boolean True if the attribute has been modified since parsing (NOT YET IMPLEMENTED!) */
|
||
|
|
var $specified = false;
|
||
|
|
/** @var Object A reference to the element to which the attribute is assigned */
|
||
|
|
var $ownerElement = null;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* DOM Attr node constructor
|
||
|
|
* @param string The name of the attribute
|
||
|
|
*/
|
||
|
|
function DOMIT_Attr($name) {
|
||
|
|
$this->_constructor();
|
||
|
|
$this->nodeType = DOMIT_ATTRIBUTE_NODE;
|
||
|
|
$this->nodeName =$name;
|
||
|
|
} //DOMIT_Attr
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the name of the attribute
|
||
|
|
* @return string The name of the attribute
|
||
|
|
*/
|
||
|
|
function getName() {
|
||
|
|
return $this->nodeName;
|
||
|
|
} //getName
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Indicates whether an attribute has been modified since parsing
|
||
|
|
* @return boolean True if the node has been modified
|
||
|
|
*/
|
||
|
|
function getSpecified() {
|
||
|
|
return $this->specified;
|
||
|
|
} //getSpecified
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the value of the attribute
|
||
|
|
* @return string The value of the attribute
|
||
|
|
*/
|
||
|
|
function getValue() {
|
||
|
|
return $this->nodeValue;
|
||
|
|
} //getValue
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Sets the value of the attribute
|
||
|
|
* @param string The value of the attribute
|
||
|
|
*/
|
||
|
|
function setValue($value) {
|
||
|
|
$this->nodeValue = $value;
|
||
|
|
} //setValue
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the text contained in the current node
|
||
|
|
* @return string The text of the current node
|
||
|
|
*/
|
||
|
|
function getText() {
|
||
|
|
return $this->nodeValue;
|
||
|
|
} //getText
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Sets the text contained in the current node to $data.
|
||
|
|
* @param string The text data of the node
|
||
|
|
*/
|
||
|
|
function setText($data) {
|
||
|
|
$this->nodeValue = $data;
|
||
|
|
} //setText
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Copies a node and/or its children
|
||
|
|
* @param boolean True if all child nodes are also to be cloned
|
||
|
|
* @return Object A copy of the node and/or its children
|
||
|
|
*/
|
||
|
|
function &cloneNode($deep = false) {
|
||
|
|
$className = get_class($this);
|
||
|
|
$clone = new $className($this->nodeName);
|
||
|
|
$clone->nodeValue = $this->nodeValue;
|
||
|
|
|
||
|
|
if ($this->namespaceURI) {
|
||
|
|
$clone->namespaceURI = $this->namespaceURI;
|
||
|
|
$clone->localName = $this->localName;
|
||
|
|
}
|
||
|
|
|
||
|
|
return $clone;
|
||
|
|
} //cloneNode
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates a string representation of the node and its children
|
||
|
|
* @param boolean True if HTML readable output is desired
|
||
|
|
* @param boolean True if HTML entities should be substituted
|
||
|
|
* @return string The string representation
|
||
|
|
*/
|
||
|
|
function toString($htmlSafe = false, $subEntities = false) {
|
||
|
|
require_once(DOMIT_INCLUDE_PATH . 'xml_domit_utilities.php');
|
||
|
|
global $DOMIT_defined_entities_flip;
|
||
|
|
|
||
|
|
$result = ' ' . $this->nodeName . '="';
|
||
|
|
$result .= $subEntities ? DOMIT_Utilities::convertEntities($this->nodeValue,
|
||
|
|
$DOMIT_defined_entities_flip) : $this->nodeValue;
|
||
|
|
$result .= '"';
|
||
|
|
|
||
|
|
if ($htmlSafe) $result = $this->forHTML($result);
|
||
|
|
|
||
|
|
return $result;
|
||
|
|
} //toString
|
||
|
|
} //DOMIT_Attr
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A class representing the DOM Document Fragment node
|
||
|
|
*
|
||
|
|
* @package domit-xmlparser
|
||
|
|
* @subpackage domit-xmlparser-main
|
||
|
|
* @author John Heinstein <johnkarl@nbnet.nb.ca>
|
||
|
|
*/
|
||
|
|
class DOMIT_DocumentFragment extends DOMIT_ChildNodes_Interface {
|
||
|
|
/**
|
||
|
|
* DOM Document Fragment node constructor
|
||
|
|
*/
|
||
|
|
function DOMIT_DocumentFragment() {
|
||
|
|
$this->_constructor();
|
||
|
|
$this->nodeType = DOMIT_DOCUMENT_FRAGMENT_NODE;
|
||
|
|
$this->nodeName ='#document-fragment';
|
||
|
|
$this->nodeValue = null;
|
||
|
|
$this->childNodes = array();
|
||
|
|
} //DOMIT_DocumentFragment
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates an array representation of the node and its children
|
||
|
|
* @return Array A representation of the node and its children
|
||
|
|
*/
|
||
|
|
function toArray() {
|
||
|
|
$arReturn = array();
|
||
|
|
$total = $this->childCount;
|
||
|
|
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
$arReturn[$i] = $this->childNodes[$i]->toArray();
|
||
|
|
}
|
||
|
|
|
||
|
|
return $arReturn;
|
||
|
|
} //toArray
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Copies a node and/or its children
|
||
|
|
* @param boolean True if all child nodes are also to be cloned
|
||
|
|
* @return Object A copy of the node and/or its children
|
||
|
|
*/
|
||
|
|
function &cloneNode($deep = false) {
|
||
|
|
$className = get_class($this);
|
||
|
|
$clone = new $className();
|
||
|
|
|
||
|
|
if ($deep) {
|
||
|
|
$total = $this->childCount;
|
||
|
|
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
$currentChild =& $this->childNodes[$i];
|
||
|
|
$clone->appendChild($currentChild->cloneNode($deep));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return $clone;
|
||
|
|
} //cloneNode
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates a string representation of the node and its children
|
||
|
|
* @param boolean True if HTML readable output is desired
|
||
|
|
* @return string The string representation
|
||
|
|
*/
|
||
|
|
function toString($htmlSafe = false, $subEntities = false) {
|
||
|
|
//get children
|
||
|
|
$result = '';
|
||
|
|
$myNodes =& $this->childNodes;
|
||
|
|
$total = count($myNodes);
|
||
|
|
|
||
|
|
if ($total != 0) {
|
||
|
|
for ($i = 0; $i < $total; $i++) {
|
||
|
|
$child =& $myNodes[$i];
|
||
|
|
$result .= $child->toString(false, $subEntities);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($htmlSafe) $result = $this->forHTML($result);
|
||
|
|
|
||
|
|
return $result;
|
||
|
|
} //toString
|
||
|
|
} //DOMIT_DocumentFragment
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A class representing the DOM Comment node
|
||
|
|
*
|
||
|
|
* @package domit-xmlparser
|
||
|
|
* @subpackage domit-xmlparser-main
|
||
|
|
* @author John Heinstein <johnkarl@nbnet.nb.ca>
|
||
|
|
*/
|
||
|
|
class DOMIT_Comment extends DOMIT_CharacterData {
|
||
|
|
/**
|
||
|
|
* DOM Comment node constructor
|
||
|
|
* @param string The
|
||
|
|
*/
|
||
|
|
function DOMIT_Comment($nodeValue) {
|
||
|
|
$this->_constructor();
|
||
|
|
$this->nodeType = DOMIT_COMMENT_NODE;
|
||
|
|
$this->nodeName = '#comment';
|
||
|
|
$this->nodeValue = $nodeValue;
|
||
|
|
} //DOMIT_Comment
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the text contained in the current node
|
||
|
|
* @return string The text of the current node
|
||
|
|
*/
|
||
|
|
function getText() {
|
||
|
|
return $this->nodeValue;
|
||
|
|
} //getText
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Sets the text contained in the current node to $data.
|
||
|
|
* @param string The text data of the node
|
||
|
|
*/
|
||
|
|
function setText($data) {
|
||
|
|
$this->nodeValue = $data;
|
||
|
|
} //setText
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates an array representation of the node and its children
|
||
|
|
* @return Array A representation of the node and its children
|
||
|
|
*/
|
||
|
|
function toArray() {
|
||
|
|
return $this->toString();
|
||
|
|
} //toArray
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Copies a node and/or its children
|
||
|
|
* @param boolean True if all child nodes are also to be cloned
|
||
|
|
* @return Object A copy of the node and/or its children
|
||
|
|
*/
|
||
|
|
function &cloneNode($deep = false) {
|
||
|
|
$className = get_class($this);
|
||
|
|
$clone = new $className($this->nodeValue);
|
||
|
|
|
||
|
|
return $clone;
|
||
|
|
} //cloneNode
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates a string representation of the node and its children
|
||
|
|
* @param boolean True if HTML readable output is desired
|
||
|
|
* @return string The string representation
|
||
|
|
*/
|
||
|
|
function toString($htmlSafe = false) {
|
||
|
|
$result = '<!--' . $this->nodeValue . '-->';
|
||
|
|
|
||
|
|
if ($htmlSafe) $result = $this->forHTML($result);
|
||
|
|
|
||
|
|
return $result;
|
||
|
|
} //toString
|
||
|
|
} //DOMIT_Comment
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A class representing the DOM Processing Instruction node
|
||
|
|
*
|
||
|
|
* @package domit-xmlparser
|
||
|
|
* @subpackage domit-xmlparser-main
|
||
|
|
* @author John Heinstein <johnkarl@nbnet.nb.ca>
|
||
|
|
*/
|
||
|
|
class DOMIT_ProcessingInstruction extends DOMIT_Node {
|
||
|
|
/**
|
||
|
|
* DOM Processing Instruction node constructor
|
||
|
|
* @param string The
|
||
|
|
*/
|
||
|
|
function DOMIT_ProcessingInstruction($target, $data) {
|
||
|
|
$this->_constructor();
|
||
|
|
$this->nodeType = DOMIT_PROCESSING_INSTRUCTION_NODE;
|
||
|
|
$this->nodeName = $target;
|
||
|
|
$this->nodeValue = $data;
|
||
|
|
} //DOMIT_ProcessingInstruction
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the processing instruction target
|
||
|
|
* @return string The processing instruction target
|
||
|
|
*/
|
||
|
|
function getTarget() {
|
||
|
|
return $this->nodeName;
|
||
|
|
} //getTarget
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the processing instruction data
|
||
|
|
* @return string The processing instruction data
|
||
|
|
*/
|
||
|
|
function getData() {
|
||
|
|
return $this->nodeValue;
|
||
|
|
} //getData
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the text contained in the current node
|
||
|
|
* @return string The text of the current node
|
||
|
|
*/
|
||
|
|
function getText() {
|
||
|
|
return ($this->nodeName . ' ' . $this->nodeValue);
|
||
|
|
} //getText
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates an array representation of the node and its children
|
||
|
|
* @return Array A representation of the node and its children
|
||
|
|
*/
|
||
|
|
function toArray() {
|
||
|
|
return $this->toString();
|
||
|
|
} //toArray
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Copies a node and/or its children
|
||
|
|
* @param boolean True if all child nodes are also to be cloned
|
||
|
|
* @return Object A copy of the node and/or its children
|
||
|
|
*/
|
||
|
|
function &cloneNode($deep = false) {
|
||
|
|
$className = get_class($this);
|
||
|
|
$clone = new $className($this->nodeName, $this->nodeValue);
|
||
|
|
|
||
|
|
return $clone;
|
||
|
|
} //cloneNode
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates a string representation of the node and its children
|
||
|
|
* @param boolean True if HTML readable output is desired
|
||
|
|
* @return string The string representation
|
||
|
|
*/
|
||
|
|
function toString($htmlSafe = false) {
|
||
|
|
$result = '<' . '?' . $this->nodeName . ' ' . $this->nodeValue . '?' . '>';
|
||
|
|
|
||
|
|
if ($htmlSafe) $result = $this->forHTML($result);
|
||
|
|
|
||
|
|
return $result;
|
||
|
|
} //toString
|
||
|
|
} //DOMIT_ProcessingInstruction
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A class representing the DOM Document Type node
|
||
|
|
*
|
||
|
|
* @package domit-xmlparser
|
||
|
|
* @subpackage domit-xmlparser-main
|
||
|
|
* @author John Heinstein <johnkarl@nbnet.nb.ca>
|
||
|
|
*/
|
||
|
|
class DOMIT_DocumentType extends DOMIT_Node {
|
||
|
|
/** @var string The doctype name */
|
||
|
|
var $name;
|
||
|
|
/** @var Object True if the entity has been modified since parsing (NOT YET IMPLEMENTED!) */
|
||
|
|
var $entities;
|
||
|
|
/** @var Object A NodeList of notation nodes (NOT YET IMPLEMENTED!) */
|
||
|
|
var $notations;
|
||
|
|
/** @var Object A NodeList of elements (NOT YET IMPLEMENTED!) */
|
||
|
|
var $elements;
|
||
|
|
/** @var string The full text of the doctype */
|
||
|
|
var $text;
|
||
|
|
/** @var string The public identifier of the external subset */
|
||
|
|
var $publicID;
|
||
|
|
/** @var string The system identifier of the external subset */
|
||
|
|
var $systemID;
|
||
|
|
/** @var string The full text of internal subset */
|
||
|
|
var $internalSubset;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* DOM Document Type node constructor
|
||
|
|
* @param string The
|
||
|
|
*/
|
||
|
|
function DOMIT_DocumentType($name, $text) {
|
||
|
|
$this->_constructor();
|
||
|
|
$this->nodeType = DOMIT_DOCUMENT_TYPE_NODE;
|
||
|
|
$this->nodeName = $name;
|
||
|
|
$this->name = $name;
|
||
|
|
$this->entities = null; //implement later
|
||
|
|
$this->notations = null; //implement later
|
||
|
|
$this->elements = null; //implement later
|
||
|
|
$this->text = $text;
|
||
|
|
} //DOMIT_DocumentType
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the text contained in the current node
|
||
|
|
* @return string The text of the current node
|
||
|
|
*/
|
||
|
|
function getText() {
|
||
|
|
return $this->text;
|
||
|
|
} //getText
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the name of the doctype node
|
||
|
|
* @return string The name of the doctype node
|
||
|
|
*/
|
||
|
|
function getName() {
|
||
|
|
return $this->name;
|
||
|
|
} //getName
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates an array representation of the node and its children
|
||
|
|
* @return Array A representation of the node and its children
|
||
|
|
*/
|
||
|
|
function toArray() {
|
||
|
|
return $this->toString();
|
||
|
|
} //toArray
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Copies a node and/or its children
|
||
|
|
* @param boolean True if all child nodes are also to be cloned
|
||
|
|
* @return Object A copy of the node and/or its children
|
||
|
|
*/
|
||
|
|
function &cloneNode($deep = false) {
|
||
|
|
$className = get_class($this);
|
||
|
|
$clone = new $className($this->nodeName, $this->text);
|
||
|
|
|
||
|
|
return $clone;
|
||
|
|
} //cloneNode
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates a string representation of the node and its children
|
||
|
|
* @param boolean True if HTML readable output is desired
|
||
|
|
* @return string The string representation
|
||
|
|
*/
|
||
|
|
function toString($htmlSafe = false) {
|
||
|
|
$result = $this->text;
|
||
|
|
|
||
|
|
if ($htmlSafe) $result = $this->forHTML($result);
|
||
|
|
|
||
|
|
return $result;
|
||
|
|
} //toString
|
||
|
|
} //DOMIT_DocumentType
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A class representing the DOM Notation node (NOT YET IMPLEMENTED!)
|
||
|
|
*
|
||
|
|
* @package domit-xmlparser
|
||
|
|
* @subpackage domit-xmlparser-main
|
||
|
|
* @author John Heinstein <johnkarl@nbnet.nb.ca>
|
||
|
|
*/
|
||
|
|
class DOMIT_Notation extends DOMIT_Node {
|
||
|
|
/**
|
||
|
|
* DOM Notation node constructor (NOT YET IMPLEMENTED!)
|
||
|
|
*/
|
||
|
|
function DOMIT_Notation() {
|
||
|
|
DOMIT_DOMException::raiseException(DOMIT_NOT_SUPPORTED_ERR,
|
||
|
|
'Cannot instantiate DOMIT_Notation class. Notation nodes not yet supported.');
|
||
|
|
} //DOMIT_Notation
|
||
|
|
} //DOMIT_Notation
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Manages the generation of a DOMIT! document from SAX events
|
||
|
|
*
|
||
|
|
* @package domit-xmlparser
|
||
|
|
* @subpackage domit-xmlparser-main
|
||
|
|
* @author John Heinstein <johnkarl@nbnet.nb.ca>
|
||
|
|
*/
|
||
|
|
class DOMIT_Parser {
|
||
|
|
/** @var Object A reference to the resulting xmldoc */
|
||
|
|
var $xmlDoc = null;
|
||
|
|
/** @var Object A reference to the current node in the parsing process */
|
||
|
|
var $currentNode = null;
|
||
|
|
/** @var Object A reference to the last child in the parsing process */
|
||
|
|
var $lastChild = null;
|
||
|
|
/** @var boolean True if currently parsing a CDATA Section */
|
||
|
|
var $inCDATASection = false; //flag for Expat
|
||
|
|
/** @var boolean True if currently parsing a Text node */
|
||
|
|
var $inTextNode = false;
|
||
|
|
/** @var boolean True is CDATA Section nodes are not to be converted into Text nodes */
|
||
|
|
var $preserveCDATA;
|
||
|
|
/** @var string A container for holding the currently parsed text data */
|
||
|
|
var $parseContainer = '';
|
||
|
|
/** @var string The current docutype text */
|
||
|
|
var $parseItem = '';
|
||
|
|
/** @var boolean True if waiting for an element to which to apply namespace declaration(s) */
|
||
|
|
var $waitingForElementToDeclareNamespaces = false;
|
||
|
|
/** @var boolean True if waiting for an element to which to apply namespace declaration(s) */
|
||
|
|
var $tempNamespaceURIMap = array();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Parses xml text using Expat
|
||
|
|
* @param Object A reference to the DOM document that the xml is to be parsed into
|
||
|
|
* @param string The text to be parsed
|
||
|
|
* @param boolean True if CDATA Section nodes are not to be converted into Text nodes
|
||
|
|
* @return boolean True if the parsing is successful
|
||
|
|
*/
|
||
|
|
function parse (&$myXMLDoc, $xmlText, $preserveCDATA = true) {
|
||
|
|
$this->xmlDoc =& $myXMLDoc;
|
||
|
|
$this->lastChild =& $this->xmlDoc;
|
||
|
|
|
||
|
|
$this->preserveCDATA = $preserveCDATA;
|
||
|
|
|
||
|
|
//create instance of expat parser (should be included in php distro)
|
||
|
|
if (version_compare(phpversion(), '5.0', '<=')) {
|
||
|
|
if ($this->xmlDoc->isNamespaceAware) {
|
||
|
|
$parser = xml_parser_create_ns('');
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$parser = xml_parser_create('');
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if ($this->xmlDoc->isNamespaceAware) {
|
||
|
|
$parser = xml_parser_create_ns();
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$parser = xml_parser_create();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//set handlers for SAX events
|
||
|
|
xml_set_object($parser, $this);
|
||
|
|
xml_set_character_data_handler($parser, 'dataElement');
|
||
|
|
xml_set_default_handler($parser, 'defaultDataElement');
|
||
|
|
xml_set_notation_decl_handler($parser, 'notationElement');
|
||
|
|
xml_set_processing_instruction_handler($parser, 'processingInstructionElement');
|
||
|
|
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
|
||
|
|
|
||
|
|
if (!$this->xmlDoc->preserveWhitespace) {
|
||
|
|
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($this->xmlDoc->isNamespaceAware) {
|
||
|
|
xml_set_start_namespace_decl_handler($parser, 'startNamespaceDeclaration');
|
||
|
|
xml_set_end_namespace_decl_handler($parser, 'endNamespaceDeclaration');
|
||
|
|
xml_set_element_handler($parser, 'startElementNS', 'endElement');
|
||
|
|
$this->xmlDoc->namespaceURIMap[DOMIT_XML_NAMESPACE] = 'xml';
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
xml_set_element_handler($parser, 'startElement', 'endElement');
|
||
|
|
}
|
||
|
|
|
||
|
|
//parse out whitespace - (XML_OPTION_SKIP_WHITE = 1 does not
|
||
|
|
//seem to work consistently across versions of PHP and Expat
|
||
|
|
if (!$this->xmlDoc->preserveWhitespace) {
|
||
|
|
$xmlText = preg_replace('#>' . "[[:space:]]+" . '<#i' , '><', $xmlText);
|
||
|
|
}
|
||
|
|
|
||
|
|
$success = xml_parse($parser, $xmlText);
|
||
|
|
|
||
|
|
$this->xmlDoc->errorCode = xml_get_error_code($parser);
|
||
|
|
$this->xmlDoc->errorString = xml_error_string($this->xmlDoc->errorCode);
|
||
|
|
|
||
|
|
xml_parser_free($parser);
|
||
|
|
|
||
|
|
return $success;
|
||
|
|
} //parse
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Parses xml text using SAXY
|
||
|
|
* @param Object A reference to the DOM document that the xml is to be parsed into
|
||
|
|
* @param string The text to be parsed
|
||
|
|
* @param boolean True if CDATA Section nodes are not to be converted into Text nodes
|
||
|
|
* @return boolean True if the parsing is successful
|
||
|
|
*/
|
||
|
|
function parseSAXY(&$myXMLDoc, $xmlText, $preserveCDATA = true, $definedEntities) {
|
||
|
|
require_once(DOMIT_INCLUDE_PATH . 'xml_saxy_parser.php');
|
||
|
|
|
||
|
|
$this->xmlDoc =& $myXMLDoc;
|
||
|
|
$this->lastChild =& $this->xmlDoc;
|
||
|
|
|
||
|
|
//create instance of SAXY parser
|
||
|
|
$parser = new SAXY_Parser();
|
||
|
|
$parser->appendEntityTranslationTable($definedEntities);
|
||
|
|
|
||
|
|
//not yet implemented in SAXY!!!
|
||
|
|
$parser->preserveWhitespace = $this->xmlDoc->preserveWhitespace;
|
||
|
|
|
||
|
|
if ($this->xmlDoc->isNamespaceAware) {
|
||
|
|
$parser->setNamespaceAwareness(true);
|
||
|
|
$parser->xml_set_start_namespace_decl_handler(array(&$this, 'startNamespaceDeclaration'));
|
||
|
|
$parser->xml_set_end_namespace_decl_handler(array(&$this, 'endNamespaceDeclaration'));
|
||
|
|
$parser->xml_set_element_handler(array(&$this, 'startElementNS'), array(&$this, 'endElement'));
|
||
|
|
$this->xmlDoc->namespaceURIMap[DOMIT_XML_NAMESPACE] = 'xml';
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$parser->xml_set_element_handler(array(&$this, 'startElement'), array(&$this, 'endElement'));
|
||
|
|
}
|
||
|
|
|
||
|
|
$parser->xml_set_character_data_handler(array(&$this, 'dataElement'));
|
||
|
|
$parser->xml_set_doctype_handler(array(&$this, 'doctypeElement'));
|
||
|
|
$parser->xml_set_comment_handler(array(&$this, 'commentElement'));
|
||
|
|
$parser->xml_set_processing_instruction_handler(array(&$this, 'processingInstructionElement'));
|
||
|
|
|
||
|
|
if ($preserveCDATA) {
|
||
|
|
$parser->xml_set_cdata_section_handler(array(&$this, 'cdataElement'));
|
||
|
|
}
|
||
|
|
|
||
|
|
$success = $parser->parse($xmlText);
|
||
|
|
|
||
|
|
$this->xmlDoc->errorCode = $parser->xml_get_error_code();
|
||
|
|
$this->xmlDoc->errorString = $parser->xml_error_string($this->xmlDoc->errorCode);
|
||
|
|
|
||
|
|
return $success;
|
||
|
|
} //parseSAXY
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates and appends a new text node from the parseContainer text
|
||
|
|
*/
|
||
|
|
function dumpTextNode() {
|
||
|
|
$currentNode =& $this->xmlDoc->createTextNode($this->parseContainer);
|
||
|
|
$this->lastChild->appendChild($currentNode);
|
||
|
|
$this->inTextNode = false;
|
||
|
|
$this->parseContainer = '';
|
||
|
|
} //dumpTextNode
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Catches a start element event and processes the data
|
||
|
|
* @param Object A reference to the current SAX parser
|
||
|
|
* @param string The tag name of the current element
|
||
|
|
* @param Array An array of the element attributes
|
||
|
|
*/
|
||
|
|
function startElement(&$parser, $name, $attrs) {
|
||
|
|
if ($this->inTextNode) {
|
||
|
|
$this->dumpTextNode();
|
||
|
|
}
|
||
|
|
|
||
|
|
$currentNode =& $this->xmlDoc->createElement($name);
|
||
|
|
$this->lastChild->appendChild($currentNode);
|
||
|
|
|
||
|
|
reset ($attrs);
|
||
|
|
|
||
|
|
while (list($key, $value) = each ($attrs)) {
|
||
|
|
$currentNode->setAttribute($key, $value);
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->lastChild =& $currentNode;
|
||
|
|
} //startElement
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Catches a start element event and processes the data
|
||
|
|
* @param Object A reference to the current SAX parser
|
||
|
|
* @param string The tag name of the current element
|
||
|
|
* @param Array An array of the element attributes
|
||
|
|
*/
|
||
|
|
function startElementNS(&$parser, $name, $attrs) {
|
||
|
|
if ($this->inTextNode) {
|
||
|
|
$this->dumpTextNode();
|
||
|
|
}
|
||
|
|
|
||
|
|
$colonIndex = strrpos($name, ":");
|
||
|
|
|
||
|
|
if ($colonIndex !== false) {
|
||
|
|
//force to lower case because Expat for some reason forces to upper case
|
||
|
|
$namespaceURI = strtolower(substr($name, 0, $colonIndex));
|
||
|
|
$prefix = $this->xmlDoc->namespaceURIMap[$namespaceURI];
|
||
|
|
|
||
|
|
if ($prefix != '') {
|
||
|
|
$qualifiedName = $prefix . ":" . substr($name, ($colonIndex + 1));
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$qualifiedName = substr($name, ($colonIndex + 1));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$namespaceURI = '';
|
||
|
|
$qualifiedName = $name;
|
||
|
|
}
|
||
|
|
|
||
|
|
$currentNode =& $this->xmlDoc->createElementNS($namespaceURI, $qualifiedName);
|
||
|
|
$this->lastChild->appendChild($currentNode);
|
||
|
|
|
||
|
|
|
||
|
|
//add attributes
|
||
|
|
reset ($attrs);
|
||
|
|
|
||
|
|
while (list($key, $value) = each ($attrs)) {
|
||
|
|
$colonIndex = strrpos($key, ":");
|
||
|
|
|
||
|
|
if ($colonIndex !== false) {
|
||
|
|
//force to lower case because Expat for some reason forces to upper case
|
||
|
|
$namespaceURI = strtolower(substr($key, 0, $colonIndex));
|
||
|
|
|
||
|
|
$qualifiedName = $this->xmlDoc->namespaceURIMap[$namespaceURI] .
|
||
|
|
":" . substr($key, ($colonIndex + 1));;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
//if containing element has a namespace, technically
|
||
|
|
//attribute namespace should be added here, but we'll do it elsewhere
|
||
|
|
//so toNormalizedString outputs the same things as is input
|
||
|
|
$namespaceURI = '';
|
||
|
|
$qualifiedName = $key;
|
||
|
|
}
|
||
|
|
|
||
|
|
$currentNode->setAttributeNS($namespaceURI, $qualifiedName, $value);
|
||
|
|
}
|
||
|
|
|
||
|
|
//and add xmlns attributes
|
||
|
|
if ($this->waitingForElementToDeclareNamespaces) {
|
||
|
|
//map namespace declarations to element
|
||
|
|
foreach ($this->tempNamespaceURIMap as $key => $value) {
|
||
|
|
$currentNode->namespaceURIMap[$key] = $value ;
|
||
|
|
|
||
|
|
//xmlns prefix has prefix: http://www.w3.org/2000/xmlns/
|
||
|
|
$currentNode->setAttributeNS(DOMIT_XMLNS_NAMESPACE, ('xmlns:' . $value), $key);
|
||
|
|
}
|
||
|
|
|
||
|
|
//reset variables
|
||
|
|
$this->tempNamespaceURIMap = array();
|
||
|
|
$this->waitingForElementToDeclareNamespaces = false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->lastChild =& $currentNode;
|
||
|
|
} //startElementNS
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Catches an end element event and processes the data
|
||
|
|
* @param Object A reference to the current SAX parser
|
||
|
|
* @param string The tag name of the current element
|
||
|
|
*/
|
||
|
|
function endElement(&$parser, $name) {
|
||
|
|
if ($this->inTextNode) {
|
||
|
|
$this->dumpTextNode();
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->lastChild =& $this->lastChild->parentNode;
|
||
|
|
} //endElement
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Catches a data event and processes the text
|
||
|
|
* @param Object A reference to the current SAX parser
|
||
|
|
* @param string The current text data
|
||
|
|
*/
|
||
|
|
function dataElement(&$parser, $data) {
|
||
|
|
if (!$this->inCDATASection) {
|
||
|
|
$this->inTextNode = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->parseContainer .= $data;
|
||
|
|
} //dataElement
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Catches a CDATA Section event and processes the text
|
||
|
|
* @param Object A reference to the current SAX parser
|
||
|
|
* @param string The current text data
|
||
|
|
*/
|
||
|
|
function cdataElement(&$parser, $data) {
|
||
|
|
$currentNode =& $this->xmlDoc->createCDATASection($data);
|
||
|
|
|
||
|
|
$this->lastChild->appendChild($currentNode);
|
||
|
|
} //cdataElement
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Catches a default data event and processes the data
|
||
|
|
* @param Object A reference to the current SAX parser
|
||
|
|
* @param string The current data
|
||
|
|
*/
|
||
|
|
function defaultDataElement(&$parser, $data) {
|
||
|
|
if ((strlen($data) > 2) && ($this->parseItem == '')){
|
||
|
|
$pre = strtoupper(substr($data, 0, 3));
|
||
|
|
|
||
|
|
switch ($pre) {
|
||
|
|
case '<?X': //xml declaration
|
||
|
|
$this->processingInstructionElement($parser, 'xml', substr($data, 6, (strlen($data) - 6 - 2)));
|
||
|
|
break;
|
||
|
|
case '<!E': //dtd entity
|
||
|
|
$this->xmlDoc->doctype .= "\n " . $data;
|
||
|
|
break;
|
||
|
|
case '<![': //cdata section coming
|
||
|
|
if ($this->preserveCDATA) {
|
||
|
|
$this->inCDATASection = true;
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case '<!-': //comment
|
||
|
|
$currentNode = $this->commentElement($this, substr($data, 4, (strlen($data) - 7)));
|
||
|
|
break;
|
||
|
|
case '<!D': //doctype
|
||
|
|
$this->parseItem = 'doctype';
|
||
|
|
$this->parseContainer = $data;
|
||
|
|
break;
|
||
|
|
case ']]>': //cdata end tag
|
||
|
|
if ($this->preserveCDATA) {
|
||
|
|
$currentNode =& $this->xmlDoc->createCDATASection($this->parseContainer);
|
||
|
|
$this->lastChild->appendChild($currentNode);
|
||
|
|
$this->inCDATASection = false;
|
||
|
|
$this->parseContainer = '';
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$this->dumpTextNode();
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
switch ($this->parseItem) {
|
||
|
|
case 'doctype':
|
||
|
|
$this->parseContainer .= $data;
|
||
|
|
|
||
|
|
if ($data == '>') {
|
||
|
|
$this->doctypeElement($parser, $this->parseContainer);
|
||
|
|
$this->parseContainer = '';
|
||
|
|
$this->parseItem = '';
|
||
|
|
}
|
||
|
|
else if ($data == '[') {
|
||
|
|
$this->parseItem = 'doctype_inline';
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case 'doctype_inline':
|
||
|
|
$this->parseContainer .= $data;
|
||
|
|
|
||
|
|
if ($data == ']') {
|
||
|
|
$this->parseItem = 'doctype';
|
||
|
|
}
|
||
|
|
else if ($data{(strlen($data) - 1)} == '>') {
|
||
|
|
$this->parseContainer .= "\n ";
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} //defaultDataElement
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Catches a doctype event and processes the data
|
||
|
|
* @param Object A reference to the current SAX parser
|
||
|
|
* @param string The current data
|
||
|
|
*/
|
||
|
|
function doctypeElement(&$parser, $data) {
|
||
|
|
$start = strpos($data, '<!DOCTYPE');
|
||
|
|
$name = trim(substr($data, $start));
|
||
|
|
$end = strpos($name, ' ');
|
||
|
|
$name = substr($name, 0, $end);
|
||
|
|
|
||
|
|
$currentNode = new DOMIT_DocumentType($name, $data);
|
||
|
|
$currentNode->ownerDocument =& $this->xmlDoc;
|
||
|
|
|
||
|
|
$this->lastChild->appendChild($currentNode);
|
||
|
|
$this->xmlDoc->doctype =& $currentNode;
|
||
|
|
} //doctypeElement
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Catches a notation node event and processes the data
|
||
|
|
* @param Object A reference to the current SAX parser
|
||
|
|
* @param string The current notation data
|
||
|
|
*/
|
||
|
|
function notationElement(&$parser, $data) {
|
||
|
|
//add to doctype string
|
||
|
|
if (($this->parseItem == 'doctype_inline') || ($this->parseItem == 'doctype')) {
|
||
|
|
$this->parseContainer .= $data;
|
||
|
|
}
|
||
|
|
} //notationElement
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Catches a comment node event and processes the data
|
||
|
|
* @param Object A reference to the current SAX parser
|
||
|
|
* @param string The comment data
|
||
|
|
*/
|
||
|
|
function commentElement(&$parser, $data) {
|
||
|
|
if ($this->inTextNode) {
|
||
|
|
$this->dumpTextNode();
|
||
|
|
}
|
||
|
|
|
||
|
|
$currentNode =& $this->xmlDoc->createComment($data);
|
||
|
|
$this->lastChild->appendChild($currentNode);
|
||
|
|
} //commentElement
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Catches a processing instruction node event and processes the data
|
||
|
|
* @param Object A reference to the current SAX parser
|
||
|
|
* @param string The target of the processing instruction data
|
||
|
|
* @param string The processing instruction data
|
||
|
|
*/
|
||
|
|
function processingInstructionElement(&$parser, $target, $data) {
|
||
|
|
if ($this->inTextNode) {
|
||
|
|
$this->dumpTextNode();
|
||
|
|
}
|
||
|
|
|
||
|
|
$currentNode =& $this->xmlDoc->createProcessingInstruction($target, $data);
|
||
|
|
$this->lastChild->appendChild($currentNode);
|
||
|
|
|
||
|
|
if (strtolower($target) == 'xml') {
|
||
|
|
$this->xmlDoc->xmlDeclaration =& $currentNode;
|
||
|
|
}
|
||
|
|
} //processingInstructionElement
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Catches a start namespace declaration event and processes the data
|
||
|
|
* @param Object A reference to the current SAX parser
|
||
|
|
* @param string The namespace prefix
|
||
|
|
* @param string The namespace uri
|
||
|
|
*/
|
||
|
|
function startNamespaceDeclaration(&$parser, $prefix, $uri) {
|
||
|
|
//make uri lower case because Expat forces it to upper case for some reason
|
||
|
|
$this->xmlDoc->namespaceURIMap[strtolower($uri)] = $prefix;
|
||
|
|
|
||
|
|
//set up a switch so when the target element arrives, namespaces can be mapped to it
|
||
|
|
$this->waitingForElementToDeclareNamespaces = true;
|
||
|
|
$this->tempNamespaceURIMap[strtolower($uri)] = $prefix;
|
||
|
|
} //startNamespaceDeclaration
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Catches an end namespace declaration event
|
||
|
|
* @param Object A reference to the current SAX parser
|
||
|
|
* @param string The namespace prefix
|
||
|
|
*/
|
||
|
|
function endNamespaceDeclaration(&$parser, $prefix) {
|
||
|
|
//do nothing; could remove from map, but would hardly be optimal
|
||
|
|
} //endNamespaceDeclaration
|
||
|
|
|
||
|
|
} //DOMIT_Parser
|
||
|
|
|
||
|
|
?>
|