?
Path : /home/admin/public_html/old/libraries/rokcommon/RokCommon/ |
Current File : /home/admin/public_html/old/libraries/rokcommon/RokCommon/XMLElement.php |
<?php /** * @version $Id: XMLElement.php 10831 2013-05-29 19:32:17Z btowles $ * @author RocketTheme http://www.rockettheme.com * @copyright Copyright (C) 2007 - 2015 RocketTheme, LLC * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 only * * */ defined('ROKCOMMON') or die; /** * */ class RokCommon_XMLElement extends SimpleXMLElement { /** * Get the name of the element. * * Warning: don't use getName() as it's broken up to php 5.2.3 * * @return string */ public function name() { if (version_compare(phpversion(), '5.2.3', '>')) { return (string)$this->getName(); } // Workaround php bug number 41867, fixed in 5.2.4 return (string)$this->aaa->getName(); } /** * Legacy method to get the element data. * * @return string * @deprecated 1.6 - Feb 5, 2010 */ public function data() { return (string)$this; } /** * Legacy method gets an elements attribute by name. * * @param string * * @return string * @deprecated 1.6 - Feb 5, 2010 */ public function getAttribute($name) { return (string)$this->attributes()->$name; } /** * Legacy method gets an elements attribute by name. * * @return array * @deprecated 1.6 - Feb 5, 2010 */ // public function getAttributes() // { // $out = array(); // foreach ($this->attributes() as $key => $val) { // $out[$key] = (string)$val; // } // return $out; // } /** * Return a well-formed XML string based on SimpleXML element * * @param bool $compressed Should we use indentation and newlines ? * @param string $indent * @param int $level Indentaion level. * * @return string */ public function asFormattedXML($compressed = false, $indent = "\t", $level = 0) { $out = ''; // Start a new line, indent by the number indicated in $level $out .= ($compressed) ? '' : "\n" . str_repeat($indent, $level); // Add a <, and add the name of the tag $out .= '<' . $this->getName(); // For each attribute, add attr="value" foreach ($this->attributes() as $attr) { $out .= ' ' . $attr->getName() . '="' . htmlspecialchars((string)$attr, ENT_COMPAT, 'UTF-8') . '"'; } // If there are no children and it contains no data, end it off with a /> if (!count($this->children()) && !(string)$this) { $out .= " />"; } else { // If there are children if (count($this->children())) { // Close off the start tag $out .= '>'; $level++; // For each child, call the asFormattedXML function (this will ensure that all children are added recursively) foreach ($this->children() as $child) { $out .= $child->asFormattedXML($compressed, $indent, $level); } $level--; // Add the newline and indentation to go along with the close tag $out .= ($compressed) ? '' : "\n" . str_repeat($indent, $level); } else if ((string)$this) { // If there is data, close off the start tag and add the data $out .= '>' . htmlspecialchars((string)$this, ENT_COMPAT, 'UTF-8'); } // Add the end tag $out .= '</' . $this->getName() . '>'; } return $out; } /* The following portions as Copyright 2009 The SimpleDOM authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * $URL: https://simpledom.googlecode.com/svn/trunk/SimpleDOM.php $ */ //================================= // Factories //================================= /** * Create a SimpleDOM object from a HTML string * * @param string $source HTML source * @param mixed &$errors Passed by reference. Will be replaced by an array of * LibXMLError objects if applicable * * @return SimpleDOM */ static public function loadHTML($source, &$errors = null) { return self::fromHTML('loadHTML', $source, $errors); } /** * Create a SimpleDOM object from a HTML file * * @param string $filename Path/URL to HTML file * @param mixed &$errors Passed by reference. Will be replaced by an array of * LibXMLError objects if applicable * * @return SimpleDOM */ static public function loadHTMLFile($filename, &$errors = null) { return self::fromHTML('loadHTMLFile', $filename, $errors); } //================================= // DOM stuff //================================= /** @ignore **/ public function __call($name, $args) { $passthrough = array( // From DOMElement 'getAttribute' => 'method', 'getAttributeNS' => 'method', 'getElementsByTagName' => 'method', 'getElementsByTagNameNS' => 'method', 'hasAttribute' => 'method', 'hasAttributeNS' => 'method', 'removeAttribute' => 'method', 'removeAttributeNS' => 'method', 'setAttribute' => 'method', 'setAttributeNS' => 'method', // From DOMNode 'appendChild' => 'insert', 'insertBefore' => 'insert', 'replaceChild' => 'insert', 'cloneNode' => 'method', 'getLineNo' => 'method', 'hasAttributes' => 'method', 'hasChildNodes' => 'method', 'isSameNode' => 'method', 'lookupNamespaceURI' => 'method', 'lookupPrefix' => 'method', 'normalize' => 'method', 'removeChild' => 'method', 'nodeName' => 'property', 'nodeValue' => 'property', 'nodeType' => 'property', 'parentNode' => 'property', 'childNodes' => 'property', 'firstChild' => 'property', 'lastChild' => 'property', 'previousSibling' => 'property', 'nextSibling' => 'property', 'namespaceURI' => 'property', 'prefix' => 'property', 'localName' => 'property', 'textContent' => 'property' ); $dom = dom_import_simplexml($this); if (!isset($passthrough[$name])) { if (method_exists($dom, $name)) { throw new BadMethodCallException('DOM method ' . $name . '() is not supported'); } if (property_exists($dom, $name)) { throw new BadMethodCallException('DOM property ' . $name . ' is not supported'); } throw new BadMethodCallException('Undefined method ' . get_class($this) . '::' . $name . '()'); } switch ($passthrough[$name]) { case 'insert': if (isset($args[0]) && $args[0] instanceof SimpleXMLElement) { $args[0] = $dom->ownerDocument->importNode(dom_import_simplexml($args[0]), true); } // no break; here case 'method': foreach ($args as &$arg) { if ($arg instanceof SimpleXMLElement) { $arg = dom_import_simplexml($arg); } } unset($arg); $ret = call_user_func_array(array($dom, $name), $args); break; case 'property': $ret = $dom->$name; break; } if ($ret instanceof DOMText) { return $ret->textContent; } if ($ret instanceof DOMNode) { if ($ret instanceof DOMAttr) { /** * Methods that affect attributes can't return the attributes themselves. Instead, * we make them chainable */ return $this; } return simplexml_import_dom($ret, get_class($this)); } if ($ret instanceof DOMNodeList) { $class = get_class($this); $list = array(); $i = -1; while (++$i < $ret->length) { $node = $ret->item($i); $list[$i] = ($node instanceof DOMText) ? $node->textContent : simplexml_import_dom($node, $class); } return $list; } return $ret; } //================================= // DOM convenience methods //================================= /** * Add a new sibling before this node * * This is a convenience method. The same result can be achieved with * <code> * $node->parentNode()->insertBefore($new, $node); * </code> * * @param SimpleXMLElement $new New node * * @return SimpleDOM The inserted node */ public function insertBeforeSelf(SimpleXMLElement $new) { $tmp = dom_import_simplexml($this); $node = $tmp->ownerDocument->importNode(dom_import_simplexml($new), true); return simplexml_import_dom($this->insertNode($tmp, $node, 'before'), get_class($this)); } /** * Add a new sibling after this node * * This is a convenience method. The same result can be achieved with * <code> * $node->parentNode()->insertBefore($new, $node->nextSibling()); * </code> * * @param SimpleXMLElement $new New node * * @return SimpleDOM The inserted node */ public function insertAfterSelf(SimpleXMLElement $new) { $tmp = dom_import_simplexml($this); $node = $tmp->ownerDocument->importNode(dom_import_simplexml($new), true); return simplexml_import_dom($this->insertNode($tmp, $node, 'after'), get_class($this)); } /** * Delete this node from document * * This is a convenience method. The same result can be achieved with * <code> * $node->parentNode()->removeChild($node); * </code> * * @return void */ public function deleteSelf() { $tmp = dom_import_simplexml($this); if ($tmp->isSameNode($tmp->ownerDocument->documentElement)) { throw new BadMethodCallException('deleteSelf() cannot be used to delete the root node'); } $tmp->parentNode->removeChild($tmp); } /** * Remove this node from document * * This is a convenience method. The same result can be achieved with * <code> * $node->parentNode()->removeChild($node); * </code> * * @return SimpleDOM The removed node */ public function removeSelf() { $tmp = dom_import_simplexml($this); if ($tmp->isSameNode($tmp->ownerDocument->documentElement)) { throw new BadMethodCallException('removeSelf() cannot be used to remove the root node'); } $node = $tmp->parentNode->removeChild($tmp); return simplexml_import_dom($node, get_class($this)); } /** * Replace this node * * This is a convenience method. The same result can be achieved with * <code> * $node->parentNode()->replaceChild($new, $node); * </code> * * @param SimpleXMLElement $new New node * * @return SimpleDOM Replaced node on success */ public function replaceSelf(SimpleXMLElement $new) { $old = dom_import_simplexml($this); $new = $old->ownerDocument->importNode(dom_import_simplexml($new), true); $node = $old->parentNode->replaceChild($new, $old); return simplexml_import_dom($node, get_class($this)); } /** * Delete all elements matching a XPath expression * * @param string $xpath XPath expression * * @return integer Number of nodes removed */ public function deleteNodes($xpath) { if (!is_string($xpath)) { throw new InvalidArgumentException('Argument 1 passed to deleteNodes() must be a string, ' . gettype($xpath) . ' given'); } $nodes = $this->_xpath($xpath); if (isset($nodes[0])) { $tmp = dom_import_simplexml($nodes[0]); if ($tmp->isSameNode($tmp->ownerDocument->documentElement)) { unset($nodes[0]); } } foreach ($nodes as $node) { $node->deleteSelf(); } return count($nodes); } /** * Remove all elements matching a XPath expression * * @param string $xpath XPath expression * * @return array Array of removed nodes on success or FALSE on failure */ public function removeNodes($xpath) { if (!is_string($xpath)) { throw new InvalidArgumentException('Argument 1 passed to removeNodes() must be a string, ' . gettype($xpath) . ' given'); } $nodes = $this->_xpath($xpath); if (isset($nodes[0])) { $tmp = dom_import_simplexml($nodes[0]); if ($tmp->isSameNode($tmp->ownerDocument->documentElement)) { unset($nodes[0]); } } $return = array(); foreach ($nodes as $node) { $return[] = $node->removeSelf(); } return $return; } /** * Remove all elements matching a XPath expression * * @param string $xpath XPath expression * @param SimpleXMLElement $new Replacement node * * @return array Array of replaced nodes on success or FALSE on failure */ public function replaceNodes($xpath, SimpleXMLElement $new) { if (!is_string($xpath)) { throw new InvalidArgumentException('Argument 1 passed to replaceNodes() must be a string, ' . gettype($xpath) . ' given'); } $nodes = array(); foreach ($this->_xpath($xpath) as $node) { $nodes[] = $node->replaceSelf($new); } return $nodes; } /** * Copy all attributes from a node to current node * * @param SimpleXMLElement $src Source node * @param bool $overwrite If TRUE, overwrite existing attributes. * Otherwise, ignore duplicate attributes * * @return SimpleDOM Current node */ public function copyAttributesFrom(SimpleXMLElement $src, $overwrite = true) { $dom = dom_import_simplexml($this); foreach (dom_import_simplexml($src)->attributes as $attr) { if ($overwrite || !$dom->hasAttributeNS($attr->namespaceURI, $attr->nodeName)) { $dom->setAttributeNS($attr->namespaceURI, $attr->nodeName, $attr->nodeValue); } } return $this; } /** * Clone all children from a node and add them to current node * * This method takes a snapshot of the children nodes then append them in order to avoid infinite * recursion if the destination node is a descendant of or the source node itself * * @param SimpleXMLElement $src Source node * @param bool $deep If TRUE, clone descendant nodes as well * * @return SimpleDOM Current node */ public function cloneChildrenFrom(SimpleXMLElement $src, $deep = true) { $src = dom_import_simplexml($src); $dst = dom_import_simplexml($this); $doc = $dst->ownerDocument; $fragment = $doc->createDocumentFragment(); foreach ($src->childNodes as $child) { $fragment->appendChild($doc->importNode($child->cloneNode($deep), $deep)); } $dst->appendChild($fragment); return $this; } /** * Move current node to a new parent * * ATTENTION! using references to the old node will screw up the original document * * @param SimpleXMLElement $dst Target parent * * @return SimpleDOM Current node */ public function moveTo(SimpleXMLElement $dst) { return simplexml_import_dom(dom_import_simplexml($dst), get_class($this))->appendChild($this->removeSelf()); } /** * Return the first node of the result of an XPath expression * * @param string $xpath XPath expression * * @return mixed SimpleDOM object if any node was returned, NULL otherwise */ public function firstOf($xpath) { $nodes = $this->xpath($xpath); return (isset($nodes[0])) ? $nodes[0] : null; } //================================= // DOM extra //================================= /** * Insert a CDATA section * * @param string $content CDATA content * @param string $mode Where to add this node: 'append' to current node, * 'before' current node or 'after' current node * * @return SimpleDOM Current node */ public function insertCDATA($content, $mode = 'append') { $this->insert('CDATASection', $content, $mode); return $this; } /** * Insert a comment node * * @param string $content Comment content * @param string $mode Where to add this node: 'append' to current node, * 'before' current node or 'after' current node * * @return SimpleDOM Current node */ public function insertComment($content, $mode = 'append') { $this->insert('Comment', $content, $mode); return $this; } /** * Insert a text node * * @param string $content CDATA content * @param string $mode Where to add this node: 'append' to current node, * 'before' current node or 'after' current node * * @return SimpleDOM Current node */ public function insertText($content, $mode = 'append') { $this->insert('TextNode', $content, $mode); return $this; } /** * Insert raw XML data * * @param string $xml XML to insert * @param string $mode Where to add this tag: 'append' to current node, * 'before' current node or 'after' current node * * @return SimpleDOM Current node */ public function insertXML($xml, $mode = 'append') { $tmp = dom_import_simplexml($this); $fragment = $tmp->ownerDocument->createDocumentFragment(); /** * Disable error reporting */ $use_errors = libxml_use_internal_errors(true); if (!$fragment->appendXML($xml)) { libxml_use_internal_errors($use_errors); throw new InvalidArgumentException(libxml_get_last_error()->message); } libxml_use_internal_errors($use_errors); $this->insertNode($tmp, $fragment, $mode); return $this; } /** * Insert a Processing Instruction * * The content of the PI can be passed either as string or as an associative array. * * @param string $target Target of the processing instruction * @param string|array $data Content of the processing instruction * * @return bool TRUE on success, FALSE on failure */ public function insertPI($target, $data = null, $mode = 'before') { $tmp = dom_import_simplexml($this); $doc = $tmp->ownerDocument; if (isset($data)) { if (is_array($data)) { $str = ''; foreach ($data as $k => $v) { $str .= $k . '="' . htmlspecialchars($v) . '" '; } $data = substr($str, 0, -1); } else { $data = (string)$data; } $pi = $doc->createProcessingInstruction($target, $data); } else { $pi = $doc->createProcessingInstruction($target); } if ($pi !== false) { $this->insertNode($tmp, $pi, $mode); } return $this; } /** * Set several attributes at once * * @param array $attr Attributes as name => value pairs * @param string $ns Namespace for the attributes * * @return SimpleDOM Current node */ public function setAttributes(array $attr, $ns = null) { $dom = dom_import_simplexml($this); foreach ($attr as $k => $v) { $dom->setAttributeNS($ns, $k, $v); } return $this; } /** * Return the content of current node as a string * * Roughly emulates the innerHTML property found in browsers, although it is not meant to * perfectly match any specific implementation. * * @todo Write a test for HTML entities that can't be represented in the document's encoding * * @return string Content of current node */ public function innerHTML() { $dom = dom_import_simplexml($this); $doc = $dom->ownerDocument; $html = ''; foreach ($dom->childNodes as $child) { $html .= ($child instanceof DOMText) ? $child->textContent : $doc->saveXML($child); } return $html; } /** * Return the XML content of current node as a string * * @return string Content of current node */ public function innerXML() { $xml = $this->outerXML(); $pos = 1 + strpos($xml, '>'); $len = strrpos($xml, '<') - $pos; return substr($xml, $pos, $len); } /** * Return the XML representing this node and its child nodes * * NOTE: unlike asXML() it doesn't return the XML prolog * * @return string Content of current node */ public function outerXML() { $dom = dom_import_simplexml($this); return $dom->ownerDocument->saveXML($dom); } /** * Return all elements with the given class name * * Should work like DOM0's method * * @param string $class Class name * * @return array Array of SimpleDOM nodes */ public function getElementsByClassName($class) { if (strpos($class, '"') !== false || strpos($class, "'") !== false) { return array(); } $xpath = './/*[contains(concat(" ", @class, " "), " ' . htmlspecialchars($class) . ' ")]'; return $this->xpath($xpath); } /** * Test whether current node has given class * * @param string $class Class name * * @return bool */ public function hasClass($class) { return in_array($class, explode(' ', $this['class'])); } /** * Add given class to current node * * @param string $class Class name * * @return SimpleDOM Current node */ public function addClass($class) { if (!$this->hasClass($class)) { $current = (string)$this['class']; if ($current !== '' && substr($current, -1) !== ' ') { $this['class'] .= ' '; } $this['class'] .= $class; } return $this; } /** * Remove given class from current node * * @param string $class Class name * * @return SimpleDOM Current node */ public function removeClass($class) { while ($this->hasClass($class)) { $this['class'] = substr(str_replace(' ' . $class . ' ', ' ', ' ' . $this['class'] . ' '), 1, -1); } return $this; } //================================= // Utilities //================================= /** * Return the current element as a DOMElement * * @return DOMElement */ public function asDOM() { return dom_import_simplexml($this); } /** * Return the current node slightly prettified * * Elements will be indented, empty elements will be minified. The result isn't mean to be * perfect, I'm sure there are better prettifiers out there. * * @param string $filepath If set, save the result to this file * * @return mixed If $filepath is set, will return TRUE if the file was * succesfully written or FALSE otherwise. If $filepath isn't set, * it returns the result as a string */ public function asPrettyXML($filepath = null) { if (!extension_loaded('xsl')) { return $this->asFormattedXML(); } /** * Dump and reload this node's XML with LIBXML_NOBLANKS. * * Also import it as a DOMDocument because some older of XSLTProcessor rejected * SimpleXMLElement as a source. */ $xml = dom_import_simplexml(new SimpleXMLElement($this->asXML())); $xsl = new DOMDocument; $xsl->loadXML('<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" /> <xsl:template match="text()"> <!-- remove everything that contains only whitespace, with at least one LF --> <xsl:if test="not(normalize-space(.) = \'\' and contains(., \' \'))"> <xsl:value-of select="."/> </xsl:if> </xsl:template> <xsl:template match="node()"> <xsl:copy> <xsl:copy-of select="@*" /> <xsl:apply-templates /> </xsl:copy> </xsl:template> </xsl:stylesheet>'); $xslt = new XSLTProcessor; $xslt->importStylesheet($xsl); $result = trim($xslt->transformToXML($xml)); if (isset($filepath)) { return (bool)file_put_contents($filepath, $result); } return $result; } /** * Transform current node and return the result * * Will take advantage of {@link http://pecl.php.net/package/xslcache PECL's xslcache} * if available * * @param string $filepath Path to stylesheet * @param bool $use_xslcache If TRUE, use the XSL Cache extension if available * * @return string Result * @throws RokCommon_Exception */ public function XSLT($filepath, $use_xslcache = true) { if (!extension_loaded('xsl')) { throw new RokCommon_Exception('XSL PHP extension is not loaded. Unable to use XSLT Function.'); } if ($use_xslcache && extension_loaded('xslcache')) { $xslt = new XSLTCache; $xslt->importStylesheet($filepath); } else { $xsl = new DOMDocument; $xsl->load($filepath); $xslt = new XSLTProcessor; $xslt->importStylesheet($xsl); } return $xslt->transformToXML(dom_import_simplexml($this)); } /** * Run an XPath query and sort the result * * This method accepts any number of arguments in a way similar to {@link * http://docs.php.net/manual/en/function.array-multisort.php array_multisort()} * * <code> * // Retrieve all <x/> nodes, sorted by @foo ascending, @bar descending * $root->sortedXPath('//x', '@foo ', '@bar', SORT_DESC); * * // Same, but sort @foo numerically and @bar as strings * $root->sortedXPath('//x', '@foo ', SORT_NUMERIC, '@bar', SORT_STRING, SORT_DESC); * </code> * * @param string $xpath XPath expression * * @return void */ public function sortedXPath($xpath) { $nodes = $this->xpath($xpath); $args = func_get_args(); $args[0] =& $nodes; call_user_func_array(array(get_class($this), 'sort'), $args); return $nodes; } /** * Sort this node's children * * ATTENTION: text nodes are not supported. If current node has text nodes, they may be lost in * the process * * @return SimpleDOM This node */ public function sortChildren() { $nodes = $this->removeNodes('*'); $args = func_get_args(); array_unshift($args, null); $args[0] =& $nodes; call_user_func_array(array(get_class($this), 'sort'), $args); foreach ($nodes as $node) { $this->appendChild($node); } return $this; } /** * Sort an array of nodes * * Note that nodes are sorted in place, nothing is returned * * @see sortedXPath * * @param array &$nodes Array of SimpleXMLElement * * @return void */ static public function sort(array &$nodes) { $args = func_get_args(); unset($args[0]); $sort = array(); $tmp = array(); foreach ($args as $k => $arg) { if (is_string($arg)) { $tmp[$k] = array(); if (preg_match('#^@?[a-z_0-9]+$#Di', $arg)) { if ($arg[0] === '@') { $name = substr($arg, 1); foreach ($nodes as $node) { $tmp[$k][] = (string)$node[$name]; } } else { foreach ($nodes as $node) { $tmp[$k][] = (string)$node->$arg; } } } elseif (preg_match('#^current\\(\\)|text\\(\\)|\\.$#i', $arg)) { /** * If the XPath is current() or text() or . we use this node's textContent */ foreach ($nodes as $node) { $tmp[$k][] = dom_import_simplexml($node)->textContent; } } else { foreach ($nodes as $node) { $_nodes = $node->xpath($arg); $tmp[$k][] = (empty($_nodes)) ? '' : (string)$_nodes[0]; } } } else { $tmp[$k] = $arg; } /** * array_multisort() wants everything to be passed as reference so we have to cheat */ $sort[] =& $tmp[$k]; } $sort[] =& $nodes; call_user_func_array('array_multisort', $sort); } //================================= // Internal stuff //================================= /**#@+ * @ignore */ protected function _xpath($xpath) { $use_errors = libxml_use_internal_errors(true); $nodes = $this->xpath($xpath); libxml_use_internal_errors($use_errors); if ($nodes === false) { throw new InvalidArgumentException('Invalid XPath expression ' . $xpath); } return $nodes; } /** * @param $type * @param $content * @param $mode * * @return DOMNode */ protected function insert($type, $content, $mode) { $tmp = dom_import_simplexml($this); $method = 'create' . $type; $node = $tmp->ownerDocument->$method($content); return $this->insertNode($tmp, $node, $mode); } /** * @param DOMNode $tmp * @param DOMNode $node * @param $mode * * @return DOMNode * @throws BadMethodCallException */ protected function insertNode(DOMNode $tmp, DOMNode $node, $mode) { if ($mode === 'before' || $mode === 'after') { if ($node instanceof DOMText || $node instanceof DOMElement || $node instanceof DOMDocumentFragment) { if ($tmp->isSameNode($tmp->ownerDocument->documentElement)) { throw new BadMethodCallException('Cannot insert a ' . get_class($node) . ' node outside of the root node'); } } if ($mode === 'before') { return $tmp->parentNode->insertBefore($node, $tmp); } if ($tmp->nextSibling) { return $tmp->parentNode->insertBefore($node, $tmp->nextSibling); } return $tmp->parentNode->appendChild($node); } return $tmp->appendChild($node); } /** * NOTE: in order to support LSB, __CLASS__ would need to be replaced by get_called_class() and * this method would need to be invoked via static:: instead of self:: */ static protected function fromHTML($method, $arg, &$errors) { $old = libxml_use_internal_errors(true); $cnt = count(libxml_get_errors()); $dom = new DOMDocument; $dom->$method($arg); $errors = array_slice(libxml_get_errors(), $cnt); libxml_use_internal_errors($old); return simplexml_import_dom($dom, __CLASS__); } /**#@-*/ }