childNodes as $child) { if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) { if ($child->entities->length > 0) { return false; } } } if ($isRunningFpm === false) { libxml_disable_entity_loader($entityLoaderDisabled); } return $dom; } /** * Get a DomDocument instance or return false. * * @static * * @param string $input XML content * * @return \DOMNDocument */ public static function getDomDocument($input) { if (empty($input)) { return false; } $dom = self::scanInput($input, function ($in) { $dom = new DomDocument(); $dom->loadXml($in, LIBXML_NONET); return $dom; }); // The document is empty, there is probably some parsing errors if ($dom && $dom->childNodes->length === 0) { return false; } return $dom; } /** * Load HTML document by using a DomDocument instance or return false on failure. * * @static * * @param string $input XML content * * @return \DOMDocument */ public static function getHtmlDocument($input) { if (empty($input)) { return new DomDocument(); } if (version_compare(PHP_VERSION, '5.4.0', '>=')) { $callback = function ($in) { $dom = new DomDocument(); $dom->loadHTML($in, LIBXML_NONET); return $dom; }; } else { $callback = function ($in) { $dom = new DomDocument(); $dom->loadHTML($in); return $dom; }; } return self::scanInput($input, $callback); } /** * Convert a HTML document to XML. * * @static * * @param string $html HTML document * * @return string */ public static function htmlToXml($html) { $dom = self::getHtmlDocument(''.$html); return $dom->saveXML($dom->getElementsByTagName('body')->item(0)); } /** * Get XML parser errors. * * @static * * @return string */ public static function getErrors() { $errors = array(); foreach (libxml_get_errors() as $error) { $errors[] = sprintf('XML error: %s (Line: %d - Column: %d - Code: %d)', $error->message, $error->line, $error->column, $error->code ); } return implode(', ', $errors); } /** * Get the encoding from a xml tag. * * @static * * @param string $data Input data * * @return string */ public static function getEncodingFromXmlTag($data) { $encoding = ''; if (strpos($data, '')); $data = str_replace("'", '"', $data); $p1 = strpos($data, 'encoding='); $p2 = strpos($data, '"', $p1 + 10); if ($p1 !== false && $p2 !== false) { $encoding = substr($data, $p1 + 10, $p2 - $p1 - 10); $encoding = strtolower($encoding); } } return $encoding; } /** * Get the charset from a meta tag. * * @static * * @param string $data Input data * * @return string */ public static function getEncodingFromMetaTag($data) { $encoding = ''; if (preg_match('/;]+)/i', $data, $match) === 1) { $encoding = strtolower($match[1]); } return $encoding; } /** * Rewrite XPath query to use namespace-uri and local-name derived from prefix. * * @param string $query XPath query * @param array $ns Prefix to namespace URI mapping * * @return string */ public static function replaceXPathPrefixWithNamespaceURI($query, array $ns) { return preg_replace_callback('/([A-Z0-9]+):([A-Z0-9]+)/iu', function ($matches) use ($ns) { // don't try to map the special prefix XML if (strtolower($matches[1]) === 'xml') { return $matches[0]; } return '*[namespace-uri()="'.$ns[$matches[1]].'" and local-name()="'.$matches[2].'"]'; }, $query); } /** * Get the result elements of a XPath query. * * @param \SimpleXMLElement $xml XML element * @param string $query XPath query * @param array $ns Prefix to namespace URI mapping * * @return \SimpleXMLElement */ public static function getXPathResult(SimpleXMLElement $xml, $query, array $ns = array()) { if (!empty($ns)) { $query = static::replaceXPathPrefixWithNamespaceURI($query, $ns); } return $xml->xpath($query); } }