/** * Given an XSLT stylesheet, run a transformation. * * This will attempt to read the provided stylesheet and then * execute it on the current source document. * * @param mixed $style * This takes a QueryPath object or <em>any</em> of the types that the * {@link qp()} function can take. * @return QueryPath * A QueryPath object wrapping the transformed document. Note that this is a * <i>different</em> document than the original. As such, it has no history. * You cannot call {@link QueryPath::end()} to undo a transformation. (However, * the original source document will remain unchanged.) */ public function xslt($style) { if (!$style instanceof QueryPath) { $style = \QueryPath::with($style); } $sourceDoc = $this->src->top()->get(0)->ownerDocument; $styleDoc = $style->get(0)->ownerDocument; $processor = new \XSLTProcessor(); $processor->importStylesheet($styleDoc); return \QueryPath::with($processor->transformToDoc($sourceDoc)); }
public function current() { if (!isset($this->qp)) { $this->qp = \QueryPath::with(parent::current(), NULL, $this->options); } else { $splos = new \SplObjectStorage(); $splos->attach(parent::current()); $this->qp->setMatches($splos); } return $this->qp; }
public static function qp($document = NULL, $selector = NULL, $options = array()) { self::$qp = false; // NOTE: we do this output buffer trick to contain any output it might make, but strlen the output afterwards // if there was a problem, surely it'll be non-zero if it outputs anything, but we prevent this // from breaking the output of the system, so we contain the problem, although we don't skip it // or even control it, because I haven't found a way to safely do that without breaking other stuff ob_start(); self::$qp = QueryPath::with($document, $selector, $options); $warnings = ob_get_clean(); // Something went wrong, but didn't trigger an exception if (strlen($warnings)) { Amslib_Debug::log("QueryPath did not produce clean output when processing document, this is not normal", $warnings); } return self::$qp; }
public function testAppendWithChildSelector() { $q = \QueryPath::with('<p>child content</p>'); $this->atts['childViewContainer'] = ".container"; $this->obj = new \JHM\Template($this->atts, $this->q); $atts = json_decode('{ "id": "childItem", "tagName": "div", "attributes": { "className": "childitem" } }', true); $expected = '<div>This be the rendered content<div class="container"><div class="childitem"><p>child content</p></div></div></div>'; $child = new \JHM\Template($atts, $q); $this->obj->appendChild($child); $this->assertEquals($expected, $this->obj->body()); }
/** * Build a new Query Path. * This builds a new Query Path object. The new object can be used for * reading, search, and modifying a document. * * While it is permissible to directly create new instances of a QueryPath * implementation, it is not advised. Instead, you should use this function * as a factory. * * Example: * @code * <?php * qp(); // New empty QueryPath * qp('path/to/file.xml'); // From a file * qp('<html><head></head><body></body></html>'); // From HTML or XML * qp(QueryPath::XHTML_STUB); // From a basic HTML document. * qp(QueryPath::XHTML_STUB, 'title'); // Create one from a basic HTML doc and position it at the title element. * * // Most of the time, methods are chained directly off of this call. * qp(QueryPath::XHTML_STUB, 'body')->append('<h1>Title</h1>')->addClass('body-class'); * ?> * @endcode * * This function is used internally by QueryPath. Anything that modifies the * behavior of this function may also modify the behavior of common QueryPath * methods. * * <b>Types of documents that QueryPath can support</b> * * qp() can take any of these as its first argument: * * - A string of XML or HTML (See {@link XHTML_STUB}) * - A path on the file system or a URL * - A {@link DOMDocument} object * - A {@link SimpleXMLElement} object. * - A {@link DOMNode} object. * - An array of {@link DOMNode} objects (generally {@link DOMElement} nodes). * - Another {@link QueryPath} object. * * Keep in mind that most features of QueryPath operate on elements. Other * sorts of DOMNodes might not work with all features. * * <b>Supported Options</b> * - context: A stream context object. This is used to pass context info * to the underlying file IO subsystem. * - encoding: A valid character encoding, such as 'utf-8' or 'ISO-8859-1'. * The default is system-dependant, typically UTF-8. Note that this is * only used when creating new documents, not when reading existing content. * (See convert_to_encoding below.) * - parser_flags: An OR-combined set of parser flags. The flags supported * by the DOMDocument PHP class are all supported here. * - omit_xml_declaration: Boolean. If this is TRUE, then certain output * methods (like {@link QueryPath::xml()}) will omit the XML declaration * from the beginning of a document. * - format_output: Boolean. If this is set to TRUE, QueryPath will format * the HTML or XML output to make it more readible. If this is set to * FALSE, QueryPath will minimize whitespace to keep the document smaller * but harder to read. * - replace_entities: Boolean. If this is TRUE, then any of the insertion * functions (before(), append(), etc.) will replace named entities with * their decimal equivalent, and will replace un-escaped ampersands with * a numeric entity equivalent. * - ignore_parser_warnings: Boolean. If this is TRUE, then E_WARNING messages * generated by the XML parser will not cause QueryPath to throw an exception. * This is useful when parsing * badly mangled HTML, or when failure to find files should not result in * an exception. By default, this is FALSE -- that is, parsing warnings and * IO warnings throw exceptions. * - convert_to_encoding: Use the MB library to convert the document to the * named encoding before parsing. This is useful for old HTML (set it to * iso-8859-1 for best results). If this is not supplied, no character set * conversion will be performed. See {@link mb_convert_encoding()}. * (QueryPath 1.3 and later) * - convert_from_encoding: If 'convert_to_encoding' is set, this option can be * used to explicitly define what character set the source document is using. * By default, QueryPath will allow the MB library to guess the encoding. * (QueryPath 1.3 and later) * - strip_low_ascii: If this is set to TRUE then markup will have all low ASCII * characters (<32) stripped out before parsing. This is good in cases where * icky HTML has (illegal) low characters in the document. * - use_parser: If 'xml', Parse the document as XML. If 'html', parse the * document as HTML. Note that the XML parser is very strict, while the * HTML parser is more lenient, but does enforce some of the DTD/Schema. * <i>By default, QueryPath autodetects the type.</i> * - escape_xhtml_js_css_sections: XHTML needs script and css sections to be * escaped. Yet older readers do not handle CDATA sections, and comments do not * work properly (for numerous reasons). By default, QueryPath's *XHTML methods * will wrap a script body with a CDATA declaration inside of C-style comments. * If you want to change this, you can set this option with one of the * JS_CSS_ESCAPE_* constants, or you can write your own. * - QueryPath_class: (ADVANCED) Use this to set the actual classname that * {@link qp()} loads as a QueryPath instance. It is assumed that the * class is either {@link QueryPath} or a subclass thereof. See the test * cases for an example. * * @ingroup querypath_core * @param mixed $document * A document in one of the forms listed above. * @param string $string * A CSS 3 selector. * @param array $options * An associative array of options. Currently supported options are listed above. * @return QueryPath */ function qp($document = NULL, $string = NULL, $options = array()) { return QueryPath::with($document, $string, $options); }
/** * Branch the base DOMQuery into another one with the same matches. * * This function makes a copy of the DOMQuery object, but keeps the new copy * (initially) pointed at the same matches. This object can then be queried without * changing the original DOMQuery. However, changes to the elements inside of this * DOMQuery will show up in the DOMQuery from which it is branched. * * Compare this operation with {@link cloneAll()}. The cloneAll() call takes * the current DOMNode object and makes a copy of all of its matches. You continue * to operate on the same DOMNode object, but the elements inside of the DOMQuery * are copies of those before the call to cloneAll(). * * This, on the other hand, copies <i>the DOMQuery</i>, but keeps valid * references to the document and the wrapped elements. A new query branch is * created, but any changes will be written back to the same document. * * In practice, this comes in handy when you want to do multiple queries on a part * of the document, but then return to a previous set of matches. (see {@link QPTPL} * for examples of this in practice). * * Example: * * @code * <?php * $qp = qp( QueryPath::HTML_STUB); * $branch = $qp->branch(); * $branch->find('title')->text('Title'); * $qp->find('body')->text('This is the body')->writeHTML; * ?> * @endcode * * Notice that in the code, each of the DOMQuery objects is doing its own * query. However, both are modifying the same document. The result of the above * would look something like this: * * @code * <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> * <html xmlns="http://www.w3.org/1999/xhtml"> * <head> * <meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta> * <title>Title</title> * </head> * <body>This is the body</body> * </html> * @endcode * * Notice that while $qp and $banch were performing separate queries, they * both modified the same document. * * In jQuery or a browser-based solution, you generally do not need a branching * function because there is (implicitly) only one document. In QueryPath, there * is no implicit document. Every document must be explicitly specified (and, * in most cases, parsed -- which is costly). Branching makes it possible to * work on one document with multiple DOMNode objects. * * @param string $selector * If a selector is passed in, an additional {@link find()} will be executed * on the branch before it is returned. (Added in QueryPath 2.0.) * @retval object DOMQuery * A copy of the DOMQuery object that points to the same set of elements that * the original DOMQuery was pointing to. * @since 1.1 * @see cloneAll() * @see find() */ public function branch($selector = NULL) { $temp = \QueryPath::with($this->matches, NULL, $this->options); //if (isset($selector)) $temp->find($selector); $temp->document = $this->document; if (isset($selector)) { $temp->findInPlace($selector); } return $temp; }
/** * Internal recursive list generator for appendList. */ protected function listImpl($items, $type, $opts, $q = NULL) { $ele = '<' . $type . '/>'; if (!isset($q)) { $q = \QueryPath::with()->append($ele)->addClass($opts['list class']); } foreach ($items as $li) { if ($li instanceof QueryPath) { $q = $this->listImpl($li->get(), $type, $opts, $q); } elseif (is_array($li) || $li instanceof Traversable) { $q->append('<li><ul/></li>')->find('li:last > ul'); $q = $this->listImpl($li, $type, $opts, $q); $q->parent(); } else { $q->append('<li>' . $li . '</li>'); } } return $q; }
public function testEnable() { \QueryPath::enable('\\QueryPath\\Tests\\DummyExtension'); $qp = \QueryPath::with(\QueryPath::XHTML_STUB); $this->assertTrue($qp->grrrrrrr()); }