diff --git a/composer.json b/composer.json
index 5fc1970c..b15ac0be 100644
--- a/composer.json
+++ b/composer.json
@@ -24,7 +24,9 @@
],
"require": {
"php": "^7.1 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0",
- "masterminds/html5": "^2.0"
+ "masterminds/html5": "^2.0",
+ "ext-dom": "*",
+ "ext-simplexml": "*"
},
"autoload": {
"psr-4": {
diff --git a/examples/at_a_glance.php b/examples/at_a_glance.php
deleted file mode 100644
index 5f95a5f2..00000000
--- a/examples/at_a_glance.php
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
This example parses a .docx file, traverse the nodes and displays the text with basic formatting. The contents of the example.xml file is the data extracted from the .docx file that QueryPath processes.
';
+
+echo '
+
+
+ This is the DOM description...
+
+
+
+ This is the Traversing description...
+
+
+
+ This is the Filtering description...
+
+
+
+ This is the Selectors description...
+
+
+EOF;
+
+try {
+ echo 'Basic HTML Usage
';
+ echo 'The following HTML chunk will get parsed, traverse, filtered, and manipulated:';
+ echo '' . htmlspecialchars($html) . '
';
+
+ echo 'Example 1
';
+ echo 'Add the attribute class="cell"
to all <td>
elements:';
+
+ echo '<?php
+
+echo html5qp($html, "td")
+->attr("class", "cell")
+->parents("table")
+->html()
+
';
+
+ echo 'This will output the following HTML:';
+
+ echo '';
+
+ echo htmlspecialchars(
+ html5qp($html, 'td')
+ ->attr('class', 'cell')
+ ->parents('table') // traverse up the DOM until we match the table
+ ->html() // get the HTML of the table
+ );
+
+ echo '
';
+
+ echo 'If you want to output a valid HTML document, replace parents(\'table\')
with top()
:';
+
+ echo '';
+
+ echo htmlspecialchars(
+ html5qp($html, 'td')
+ ->attr('class', 'cell')
+ ->top()
+ ->html()
+ );
+
+ echo '
';
+
+ echo 'Example 2
';
+ echo 'Find and output the text of the second cell in the second row of the table:';
+
+ $text = html5qp($html)
+ ->find('#row2 > td:nth-child(2)')
+ ->text();
+
+ echo '<?php
+
+echo html5qp($html)
+->find("#row2 > td:nth-child(2)")
+->text();
+
+// Result: '. $text. '
+
';
+
+ echo 'Example 3
';
+ echo 'Append an additional row at the end of the table:';
+ echo '<?php
+
+echo html5qp($html, "td")
+->after("<tr><td>seven</td><td>eight</td><td>nine</td></tr>")
+->parents("table") // traverse up the DOM until we match the table
+->html()
+
';
+
+ echo 'This will output the following HTML:';
+
+ echo '';
+
+ echo htmlspecialchars(
+ html5qp($html, 'tr:last')
+ ->after("\n\n\t\n\t\tseven | \n\t\teight | \n\t\tnine | \n\t
")
+ ->parents('table')
+ ->html()
+ );
+
+ echo '
';
+
+ echo 'Basic XML Usage
';
+ echo 'The following XML will get parsed, traverse, filtered, and manipulated:';
+ echo '' . htmlspecialchars($xml) . '
';
+
+ echo 'Example 1
';
+ echo 'Add the attribute class="item"
to all <desc>
elements:';
+
+ echo '<?php
+
+echo qp($xml, "desc")
+->attr("class", "item)
+->top() // return to the root node (<categories>)
+->xml(); // output a valid XML document.
+
';
+
+ echo 'This will output the following XML:';
+
+ echo '';
+
+ echo htmlspecialchars(
+ qp($xml, 'desc')
+ ->attr('class', 'item')
+ ->top() // return to the root node
+ ->xml() // output a valid XML document
+ );
+
+ echo '
';
+
+ echo 'You can omit the XML declaration by setting the first argument to true: ->xml(true)
.';
+
+ echo 'Example 2
';
+ echo 'Find and output the text of the third <desc>
tag:';
+
+ $text = qp($xml)
+ ->find('categories > category:nth-child(3) desc')
+ ->text();
+
+ echo '<?php
+
+echo qp($xml)
+->find("categories > category:nth-child(3) desc")
+->text();
+
+ // Result: '.$text.'
+
';
+
+ echo 'Example 3
';
+ echo 'Append a category at the end of the group:';
+ echo '<?php
+
+echo qp($xml, "category:last")
+->after("<category name=\'Appended\'><desc>The appended node...</desc></category>")
+->top()
+->xml()
+
';
+
+ echo 'This will output the following HTML:';
+
+ echo '';
+
+ echo htmlspecialchars(
+ qp($xml, 'category:last')
+ ->after("\n\n\t\n\t\tThe appended node...\n\t")
+ ->top()
+ ->xml()
+ );
+
+ echo '
';
+} catch (\QueryPath\Exception $e) {
+ // Handle QueryPath exceptions
+ die($e->getMessage());
+}
diff --git a/examples/create-html-document/index.php b/examples/create-html-document/index.php
new file mode 100644
index 00000000..7ba80c20
--- /dev/null
+++ b/examples/create-html-document/index.php
@@ -0,0 +1,118 @@
+
+ * @license LGPL The GNU Lesser GPL (LGPL) or an MIT-like license.
+ */
+
+require_once __DIR__ . '/../../vendor/autoload.php';
+
+echo 'Building a HTML Document with QueryPath
';
+
+echo 'You can use QueryPath to build complex HTML documents using a simple jQuery-like API:';
+
+//TODO - consider writeHTML() instead of html()
+
+echo '<?php
+
+// Begin with an HTML5 stub document and navigate to the title.
+echo html5qp(\QueryPath\QueryPath::HTML5_STUB, "title")
+ // Add text to the title
+ ->text("Example of QueryPath.")
+ // Traverse to the root of the document, then locate the body tag
+ ->top("body")
+ // Inside the body, add a heading and paragraph.
+ ->append("<h1>This is a test page</h1><p>Test text</p>")
+ // Select the paragraph we just created inside the body
+ ->children("p")
+ // Add a class attribute to the paragraph
+ ->attr("class", "some-class")
+ // And an inline style to the paragraph
+ ->css("background-color", "#eee")
+ // Traverse back up the DOM to the body
+ ->parent()
+ // Add an empty table to the body, before the heading
+ ->prepend("<table id=\'my-table\'></table>")
+ // Now go to the table...
+ ->find("#my-table")
+ // Add a couple of empty rows
+ ->append("<tr></tr><tr></tr>")
+ // select the rows (both at once)
+ ->children()
+ // Add a CSS class to both rows
+ ->addClass("table-row")
+ // Get the first row (at position 0)
+ ->eq(0)
+ // Add a table header in the first row
+ ->append("<th>This is the header</th>")
+ // Now go to the next row
+ ->next()
+ // Add some data to this row
+ ->append("<td>This is the data</td>")
+ // Traverse to the root of the document
+ ->top()
+ // Write it all out as HTML
+ ->html();
+';
+
+echo '
';
+
+echo 'Results
';
+
+try {
+ echo '';
+
+ echo htmlspecialchars(
+ // Begin with an HTML5 stub document and navigate to the title.
+ html5qp(\QueryPath\QueryPath::HTML5_STUB, 'title')
+ // Add text to the title
+ ->text('Example of QueryPath.')
+ // Traverse to the root of the document, then locate the body tag
+ ->top('body')
+ // Inside the body, add a heading and paragraph.
+ ->append('This is a test page
Test text
')
+ // Select the paragraph we just created inside the body
+ ->children('p')
+ // Add a class attribute to the paragraph
+ ->attr('class', 'some-class')
+ // And an inline style to the paragraph
+ ->css('background-color', '#eee')
+ // Traverse back up the DOM to the body
+ ->parent()
+ // Add an empty table to the body, before the heading
+ ->prepend('')
+ // Now let's go to the table...
+ ->find('#my-table')
+ // Add a couple of empty rows
+ ->append('|
')
+ // select the rows (both at once)
+ ->children()
+ // Add a CSS class to both rows
+ ->addClass('table-row')
+ // Get the first row (at position 0)
+ ->eq(0)
+ // Add a table header in the first row
+ ->append('This is the header | ')
+ // Now go to the next row
+ ->next()
+ // Add some data to this row
+ ->append('This is the data | ')
+ // Traverse to the root of the document
+ ->top()
+ // Write it all out as HTML
+ ->html()
+ );
+
+ echo '
';
+} catch (\QueryPath\Exception $e) {
+ die($e->getMessage());
+}
diff --git a/examples/create-xml-document/index.php b/examples/create-xml-document/index.php
new file mode 100644
index 00000000..e5c6c6f7
--- /dev/null
+++ b/examples/create-xml-document/index.php
@@ -0,0 +1,58 @@
+`
+ *
+ * @author M Butcher
+ * @license LGPL The GNU Lesser GPL (LGPL) or an MIT-like license.
+ */
+
+require_once __DIR__ . '/../../vendor/autoload.php';
+
+/*
+ * Create a new XML document wrapped in a QueryPath.
+ * By default, it will point to the root element ``
+ */
+
+//TODO
+// Use QueryPath::withXML() will allow you to omit the XML declaration ""
+// \QueryPath\QueryPath::withXML('')
+// ->append('Wiseman')
+// ->writeXML();
+
+try {
+ qp('')
+ // Add a new last name inside of author.
+ ->append('Wiseman')
+ // Select all of the children of . In this case,
+ // that is
+ ->children()
+ // Oh, wait... we wanted last name to be inside of a
+ // element. Use wrap to wrap the current element in something:
+ ->wrap('')
+ // And before last name, we want to add first name.
+ ->before('')
+ // Select first name
+ ->prev()
+ // Set the text of first name
+ ->text('Simon')
+ // And then after first name, add the patronymic
+ ->after('J.')
+ // Now go back to the root element, the top of the document.
+ ->top()
+ // Add another tag -- origin.
+ ->append('Australia')
+ // turn the QueryPath contents back into a string. Since we are
+ // at the top of the document, the whole document will be converted
+ // to a string.
+ ->writeXML();
+} catch (\QueryPath\Exception $e) {
+ die($e->getMessage());
+}
diff --git a/examples/curl-xml-filter-and-retrival/index.php b/examples/curl-xml-filter-and-retrival/index.php
new file mode 100644
index 00000000..b8eb23dc
--- /dev/null
+++ b/examples/curl-xml-filter-and-retrival/index.php
@@ -0,0 +1,103 @@
+
+ * @license LGPL The GNU Lesser GPL (LGPL) or an MIT-like license.
+ * @see https://musicbrainz.org
+ */
+require_once __DIR__ . '/../../vendor/autoload.php';
+
+$artist_name = 'U2';
+$artist_url = 'https://musicbrainz.org/ws/2/artist/?query=' . rawurlencode($artist_name);
+$album_url = 'https://musicbrainz.org/ws/2/release-group?&artist=';
+
+try {
+ /* Make a remote cURL request to get the XML */
+ $artist_xml = get($artist_url);
+
+ /* Load the XML into QueryPath and select the first artist in the list */
+ $artist = qp($artist_xml, 'artist:first');
+
+ /* Check if nothing in the XML matched the selector */
+ if (count($artist) === 0) {
+ echo 'No results found
';
+ exit;
+ }
+
+ /* Get direct children of "artist", filter by the "name" tag, and output the text */
+ echo sprintf('Albums by %s
', $artist->children('name')->text());
+
+ /* Get the unique albums listed for this artist */
+ $id = $artist->attr('id');
+ $album_url .= rawurlencode($id);
+ $albums_xml = get($album_url);
+
+ /* Load the XML into QueryPath */
+ $albums = qp($albums_xml, 'release-group');
+
+ /* Loop over the results */
+ echo '';
+ foreach ($albums as $album) {
+ echo sprintf(
+ '- %1$s (%2$s)
',
+ $album->find('title')->text(),
+ $album->find('first-release-date')->text()
+ );
+ }
+ echo '
';
+
+ /* The XML retrieved via cURL and fed into QueryPath */
+ echo 'XML
';
+
+ echo 'Artists
';
+ echo sprintf('%s
', $artist_url);
+ echo '';
+ echo htmlspecialchars($artist->top()->xml());
+ echo '
';
+
+ echo 'Albums
';
+ echo sprintf('%s
', $album_url);
+ echo '';
+ echo htmlspecialchars($albums->top()->xml());
+ echo '
';
+
+} catch (Exception $e) {
+ echo $e->getMessage();
+}
+
+/**
+ * Make a GET request using cURL and return the results
+ *
+ * @param string $url
+ * @return string
+ */
+function get($url)
+{
+ $defaults = array(
+ CURLOPT_URL => $url,
+ CURLOPT_HEADER => 0,
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_FAILONERROR => true,
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_USERAGENT => 'QueryPath/3.0'
+ );
+
+ $ch = curl_init();
+
+ curl_setopt_array($ch, $defaults);
+
+ if (!$result = curl_exec($ch)) {
+ throw new RuntimeException(curl_error($ch));
+ }
+
+ curl_close($ch);
+
+ return $result;
+}
diff --git a/examples/database_import.php b/examples/database_import.php
deleted file mode 100644
index 308fd947..00000000
--- a/examples/database_import.php
+++ /dev/null
@@ -1,62 +0,0 @@
-
- * @license LGPL The GNU Lesser GPL (LGPL) or an MIT-like license.
- */
-
-require_once '../src/QueryPath/QueryPath.php';
-require_once '../src/QueryPath/Extension/QPDB.php';
-
-// Set the default database.
-QPDB::baseDB('sqlite:../test/db/qpTest.db');
-
-// To begin, let's create a new database. We can do this outside
-// of QueryPath:
-$db = QPDB::getBaseDB();
-$db->exec('CREATE TABLE IF NOT EXISTS qpdb_article (title, author, body)');
-
-// Here's our sample article:
-$article = '
-
- Use QueryPath for Fun and Profit
-
- Matt
- Butcher
-
-
- QueryPath is a great tool.
- Use it in many ways.
- ]]>
-
-';
-
-// Now let's take this article and insert it into the database:
-$qp = qp($article);
-
-// We are going to store our insert params in here.
-$params = [];
-
-// First, let's get the title
-$params[':title'] = $qp->find('title')->text();
-
-// Next, let's get the name:
-$params[':name'] = $qp->top()->find('author>last')->text() . ', ' . $qp->prev('first')->text();
-
-// Finally, let's get the article content:
-$params[':body'] = $qp->top()->find('body')->text();
-
-// Here's the query we are going to run:
-$sql = 'INSERT INTO qpdb_article (title, author, body) VALUES (:title, :name, :body)';
-
-// Now we can insert this:
-$qp->query($sql, $params);
-
-// Finally, we can now read this information back out into an HTML document
-qp(QueryPath::HTML_STUB, 'body')->queryInto('SELECT * FROM qpdb_article')->writeHTML();
-
-// Finally, we clean up:
-$qp->exec('DROP TABLE qpdb_article');
diff --git a/examples/dbpedia.php b/examples/dbpedia.php
deleted file mode 100644
index b4f4f0c5..00000000
--- a/examples/dbpedia.php
+++ /dev/null
@@ -1,98 +0,0 @@
-
- * @license LGPL The GNU Lesser GPL (LGPL) or an MIT-like license.
- * @see http://www.w3.org/DesignIssues/LinkedData.html
- * @see http://dbpedia.org
- * @see sparql.php
- * @see musicbrainz.php
- */
-
-require_once '../src/QueryPath/QueryPath.php';
-
-// The URL to look up (any of these works):
-$url = 'http://dbpedia.org/data/The_Beatles.rdf';
-//$url = 'http://dbpedia.org/data/Swansea.rdf';
-//$url = 'http://dbpedia.org/data/The_Lord_of_the_Rings.rdf';
-// HTTP headers:
-$headers = [
- 'Accept: application/rdf,application/rdf+xml;q=0.9,*/*;q=0.8',
- 'Accept-Language: en-us,en',
- 'Accept-Charset: ISO-8859-1,utf-8',
- 'User-Agent: QueryPath/1.2',
-];
-
-// The context options:
-$options = [
- 'http' => [
- 'method' => 'GET',
- 'protocol_version' => 1.1,
- 'header' => implode("\r\n", $headers),
- ],
-];
-
-// Create a stream context that will tell QueryPath how to
-// load the file.
-$cxt = stream_context_create($options);
-
-// Fetch the URL and select all rdf:Description elements.
-// (Note that | is the CSS 3 equiv of colons for namespacing.)
-// To add the context, we pass it in as an option to QueryPath.
-$qp = qp($url, 'rdf|Description', ['context' => $cxt]);
-//$qp = qp('The_Beatles.rdf');
-
-printf("There are %d descriptions in this record.\n", $qp->size());
-
-// Here, we use rdf|* to select all elements in the RDF namespace.
-$qp->top()->find('rdf|*');
-printf("There are %d RDF items in this record.\n", $qp->size());
-
-// Standard pseudo-classes that are not HTML specific can be used on
-// namespaced elements, too.
-print "About: " . $qp->top()->find('rdfs|label:first')->text() . PHP_EOL;
-print "About (FOAF): " . $qp->top()->find('foaf|name:first')->text() . PHP_EOL;
-
-// Namespaced attributes can be retrieved using the same sort of delimiting.
-print "\nComment:\n";
-print $qp->top()->find('rdfs|comment[xml|lang="en"]')->text();
-print PHP_EOL;
-
-$qp->top();
-
-print "\nImages:\n";
-foreach ($qp->branch()->find('foaf|img') as $img) {
- // Note that when we use attr() we are using the XML name, NOT
- // the CSS 3 name. So it is rdf:resource, not rdf|resource.
- // The same goes for the tag() function -- it will return
- // the full element name (e.g. rdf:Description).
- print $img->attr('rdf:resource') . PHP_EOL;
-}
-
-print "\nImages Galleries:\n";
-foreach ($qp->branch()->find('dbpprop|hasPhotoCollection') as $img) {
- print $img->attr('rdf:resource') . PHP_EOL;
-}
-
-print "\nOther Sites:\n";
-foreach ($qp->branch()->find('foaf|page') as $img) {
- print $img->attr('rdf:resource') . PHP_EOL;
-}
-
-//$qp->writeXML();
diff --git a/examples/dirty_html.php b/examples/dirty_html.php
deleted file mode 100644
index 2c2c3e68..00000000
--- a/examples/dirty_html.php
+++ /dev/null
@@ -1,19 +0,0 @@
-Urban Dictionary Random Word Generator';
-
-$page = rand(0, 288);
-$qp = htmlqp('http://www.urbandictionary.com/?page=' . $page, '#home');
-
-$rand = rand(0, 7);
-print $qp->find('.word')->eq($rand)->text() . '
';
-print $qp->top()->find('.definition')->eq($rand)->text();
diff --git a/examples/doc.html b/examples/doc.html
deleted file mode 100644
index 4588cf18..00000000
--- a/examples/doc.html
+++ /dev/null
@@ -1,109 +0,0 @@
-
-
-
-
-Documentation
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/doc.php b/examples/doc.php
deleted file mode 100644
index f80d7eb7..00000000
--- a/examples/doc.php
+++ /dev/null
@@ -1,108 +0,0 @@
-$v
";
-}
-
-// The document skeleton
-$qpdoc = htmlqp('doc.html', 'body');
-
-$key = $_GET['key'];
-
-// The jQuery categories that are used in QueryPath
-$qparray = [
- 'Tree Traversal',
- 'Child Filter',
- 'Attribute',
- 'Content Filter',
- 'Basic Filter',
- 'Hierarchy',
- 'Basic',
- 'Filtering',
- 'Miscellaneous Traversing',
- 'DOM Insertion, Outside',
- 'DOM Insertion, Inside',
- 'Attributes',
- 'Style Properties',
-];
-
-$jqnames = [];
-$qpnames = [];
-
-// Search through the xml file to find any entries of jQuery entities
-foreach (qp('querypath.xml', 'entry') as $entry) {
- $qpnames[$entry->attr('name')] =
- [
- 'desc' => $entry->find('desc')->innerXML(),
- 'jquery' => $entry->parent()->find('jquery')->innerXML(),
- 'querypath' => $entry->parent()->find('querypath')->innerXML(),
- ];
-}
-
-// Search through the xml file to find all entries of jQuery entities
-foreach (htmlqp('http://api.jquery.com/api/', 'entry') as $entry) {
- $category = false;
- $category = array_search($entry->find('category:first')->attr('name'), $qparray);
- while ($entry->next('category')->html() != null) {
- $category = (array_search($entry->attr('name'), $qparray)) ? true : $category;
- if ($category) {
- break;
- }
- }
- if ($category) {
- $jqnames[$entry->parent()->attr('name')] =
- [
- 'longdesc' => $entry->find('longdesc')->innerXML(),
- 'name' => $entry->parent()->find('category')->attr('name'),
- ];
- }
-}
-
-// Map the keys & sort them
-$jqkeys = array_keys($jqnames);
-$jqkeys = array_map("addClasses", $jqkeys);
-sort($jqkeys);
-
-// Add the keys to the nav bar
-$qpdoc->find('#leftbody');
-foreach ($jqkeys as $k => $v) {
- $qpdoc->append($v);
-}
-
-// Add the description to the main window if the key exists
-if (array_key_exists($key, $jqnames)) {
- if (array_key_exists($key, $qpnames)) {
- $qpdoc->top()->find('#rightfunction')->text('Function: ' . ucfirst($key));
- $qpdoc->top()->find('#rightdesc')->text($qpnames[$key]['desc']);
- $qpdoc->top()->find('#righttitle')->text('How it\'s done in jQuery');
- $qpdoc->top()->find('#righttext')->text($qpnames[$key]['jquery']);
- $qpdoc->top()->find('#righttitle2')->text('How it\'s done in QueryPath');
- $qpdoc->top()->find('#righttext2')->text($qpnames[$key]['querypath']);
- } else {
- $qpdoc->top()->find('#rightfunction')->text('Function: ' . ucfirst($key));
- $qpdoc->top()->find('#rightdesc')->remove();
- $qpdoc->top()->find('#righttitle')->text('jQuery Documentation');
- $qpdoc->top()->find('#righttext')->append($jqnames[$key]['longdesc']);
- }
-}
-
-// Write the document
-$qpdoc->writeHTML();
diff --git a/examples/docx.php b/examples/docx.php
deleted file mode 100644
index e917c099..00000000
--- a/examples/docx.php
+++ /dev/null
@@ -1,116 +0,0 @@
-branch();
- print format($qr->find('w|r:first'), 'w|r:first') . ' ';
- $qp->find('w|r:first');
- while ($qp->next('w|r')->html() != null) {
- $qr = $qp->branch();
- print format($qr->find('w|r'), 'w|r') . ' ';
- // print $qp->text();
- }
- print '';
-}
-
-/**
- *
- * @param QueryPath $qp
- * @param String $findSelector
- *
- * @return String
- */
-function format($qp, $findSelector = null)
-{
-
- // Create a new branch for printing later.
- $qr = $qp->branch();
-
- $text = "";
-
- $text = $qr->find($findSelector)->find('w|t')->text();
-
- $text = (checkUnderline($qp->branch())) ? '' . $text . '' : $text;
- $text = (checkBold($qp->branch())) ? '' . $text . '' : $text;
-
- return $text;
-}
-
-/**
- *
- * @param QueryPath $qp
- *
- * @return String
- */
-function checkBold($qp)
-{
- $qp->children("w|rPr");
-
- return ($qp->children('w|b')->html()) ? true : false;
-}
-
-/**
- *
- * @param QueryPath $qp
- *
- * @return String
- */
-function checkUnderline($qp)
-{
- $qp->children("w|rPr");
-
- return ($qp->children('w|u')->html()) ? true : false;
-}
-
-
-function docx2text($filename)
-{
- return readZippedXML($filename, "word/document.xml");
-}
-
-function readZippedXML($archiveFile, $dataFile)
-{
- if (! class_exists('ZipArchive', false)) {
- return "ZipArchive Class Doesn't Exist.";
- }
- // Create new ZIP archive
- $zip = new ZipArchive();
- // Open received archive file
- if (true === $zip->open($archiveFile)) {
- // If done, search for the data file in the archive
- if (($index = $zip->locateName($dataFile)) !== false) {
- // If found, read it to the string
- $data = $zip->getFromIndex($index);
- // Close archive file
- $zip->close();
- // Load XML from a string
- // Skip errors and warnings
- return $data;
- // $xml = DOMDocument::loadXML($data, LIBXML_NOENT | LIBXML_XINCLUDE | LIBXML_NOERROR | LIBXML_NOWARNING);
- // // Return data without XML formatting tags
- // return strip_tags($xml->saveXML());
- }
- $zip->close();
- }
-
- // In case of failure return empty string
- return $zip->getStatusString();
-}
diff --git a/examples/docx_document.xml b/examples/docx_document.xml
deleted file mode 100644
index fcf8614f..00000000
--- a/examples/docx_document.xml
+++ /dev/null
@@ -1,3914 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- I. Para
-
-
-
-
-
-
-
-
- :
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1. In order to + infinitive (Hago ejercicos
-
-
-
-
-
-
-
-
-
- para
-
-
-
-
-
-
-
- rebajar) (Tomo la medicina
-
-
-
-
-
-
-
-
-
- para
-
-
-
-
-
-
-
- sentirme mejor)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 2. For = destined for, to be given to (Todo mi amor es
-
-
-
-
-
-
-
-
-
-
- para
-
-
-
-
-
-
-
-
- ti)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 3. For = by deadline, specified future time (La tarea es
-
-
-
-
-
-
-
-
-
- para
-
-
-
-
-
-
-
- el lunes)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- (Es
-
-
-
-
-
-
-
-
-
- para
-
-
-
-
-
-
-
- las cinco de la tarde)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 4. For = toward in the direction of (destination) (Sarah salió
-
-
-
-
-
-
-
-
-
-
- para
-
-
-
-
-
-
-
-
- España)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- (Manolo Salió
-
-
-
-
-
-
-
-
-
- para
-
-
-
-
-
-
-
- el campo)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 5. For = to be used for (purpose of an object) (La taza es
-
-
-
-
-
-
-
-
-
-
- para
-
-
-
-
-
-
-
-
- el café)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- (El dinero es
-
-
-
-
-
-
-
-
-
- para
-
-
-
-
-
-
-
- la matricula)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 6. For = as compared with others, in relation to others (
-
-
-
-
-
-
-
-
-
-
- Para
-
-
-
-
-
-
-
- mí, el español es fácil) (
-
-
-
-
-
-
-
-
-
- Para
-
-
-
-
-
-
-
- ser extranjero, habla muy bien el inglés)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 7. For = in the employ
-
-
-
-
-
-
-
- ment
-
-
-
-
-
-
-
- of (Trabajan
-
-
-
-
-
-
-
-
-
- para
-
-
-
-
-
-
-
- el gobierno) (Nosotros trabajamos
-
-
-
-
-
-
-
-
-
- para
-
-
-
-
-
-
-
- la universidad)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- II
-
-
-
-
-
-
-
-
-
- . Por:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1. By means of (voy a España
-
-
-
-
-
-
-
-
-
- por
-
-
-
-
-
-
-
- avión)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 2. Through, along ( Camino por el parque) (Paseo
-
-
-
-
-
-
-
-
-
- por
-
-
-
-
-
-
-
- la ciudad)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 3. Duration of time, time of day, (Trabajo
-
-
-
-
-
-
-
-
-
- por
-
-
-
-
-
-
-
- la noche, trabajo
-
-
-
-
-
-
-
-
-
- por
-
-
-
-
-
-
-
- cinco horas)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- (Voy a Perú
-
-
-
-
-
-
-
-
-
- por
-
-
-
-
-
-
-
- un año)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 4. Because of, due to (Estoy nervioso
-
-
-
-
-
-
-
-
-
- por
-
-
-
-
-
-
-
- la entrevista) (Megan tiene tos
-
-
-
-
-
-
-
-
-
- por
-
-
-
-
-
-
-
- el resfriado)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 5. For = in Exchange for (Te cambio mi BMW
-
-
-
-
-
-
-
-
-
- por
-
-
-
-
-
-
-
- tu Mercedes)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- (Compré un CD
-
-
-
-
-
-
-
-
-
- por
-
-
-
-
-
-
-
- 10 dólares)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 6. For = for the sake of, on behalf of (Lo hago
-
-
-
-
-
-
-
-
-
-
- por
-
-
-
-
-
-
-
-
- ti) (Trabajo
-
-
-
-
-
-
-
-
-
-
- por
-
-
-
-
-
-
-
-
- los niños)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 7. To do something for someone else (a favor) (Esta semana, Juan va a trabajar
-
-
-
-
-
-
-
-
-
- por
-
-
-
-
-
-
-
- María)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Por is also used with some “fixed expressions” (Know them)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Por Dios
-
-
-
-
-
-
-
-
- (for heaven’s sake)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Por ejemplo
-
-
-
-
-
-
-
- (for example)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Por ahí, por allí
-
-
-
-
-
-
-
-
-
- (around there)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Por eso
-
-
-
-
-
-
-
-
- (that’s why)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Por cierto
-
-
-
-
-
-
-
-
- (by the way)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Por favor
-
-
-
-
-
-
-
- (please)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Por fin
-
-
-
-
-
-
-
- (finally)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Por lo general
-
-
-
-
-
-
-
- (in general, generally)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Por lo menos
-
-
-
-
-
-
-
- (at least)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Por primera/última vez
-
-
-
-
-
-
-
-
- (for the first/last time)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Por si acaso
-
-
-
-
-
-
-
- (just in case)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Por supuesto
-
-
-
-
-
-
-
- (of course)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Por todas partes
-
-
-
-
-
-
-
- (everywhere)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Por ahora
-
-
-
-
-
-
-
- (for now)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Por lo visto
-
-
-
-
-
-
-
- (apparently)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Por último
-
-
-
-
-
-
-
- (finally)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- A.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Por y Para 1-
-
-
-
-
-
-
-
-
- Un viaje a Costa Rica-Write por or para in the lines below, depending on the context.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Ellos hicieron un viaje a Costa Rica ______________
- (1)cinco semanas. Viajaron ______________(2) avión y cuando
- llegaron al país, tomaron unos taxis______________(3) ir a su
- hotel.____________(4) ser viajeros en un país extranjero,
- tenían mucho miedo al principio del viaje. Cuando llegaron al
- hotel, entraron _____________(5) las puertas principales y
- subieron ______________(6) el elevador para llegar a sus
- propias habitaciones. Estaban emocionados de ir a este nuevo
- país____________(7) conocer sus lugares turisticos.
- ____________(8) disfrutar del lugar, ellos salían a los discos
- ___________(9) las noches. Después de entrar en las
- discos___________(10) bailar, podían comprar bebidas caras.
- Casi siempre cuesta menos de dos dólares_____________(11) una
- cerveza. Pero hay muchas otras cosas que hicieron durante su
- visita. Ellos no fueron allá solamente ___________(12)
- festejar. Hay muchas cosas diferentes en Costa Rica que no hay
- en los Estados Unidos.__________(13) ejemplo, el paisaje es
- algo que no se puede encontrar en todas partes del mundo. La
- mayoría de los estudiantes gozaron su viaje y les
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- gustaría ir__________(14) Latinoamérica otra vez.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- B. Por y Para 2-
-
-
-
-
-
-
-
- Complete los siguientes diálogos y oraciones utilizando por
- o para:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1. Carla, Kyra y Melissa salieron__________Pepe’s ayer. Van
- a Pepe’s _________coche y luego de ir a Pepe’s irán a pa
-
-
-
-
-
-
-
- s
-
-
-
-
-
-
-
- ear _________toda la ciudad. Va a ser una buena experiencia
- ________las tres.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 2. Mi hermano Miguel quiere estudiar __________ser doctor.
- ________eso, trabaja _________mi madre que es médica. Trabaja
- _________las mañanas y __________las tardes. Trabaja
- _________muchas horas
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- _________obtener más experiencia.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 3. ________lo general, Joel es una persona muy amable.
- ________ejemplo, la semana pasado nos trajo donas y galletas.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 4. El cuadro de Guernica fue pintado ________Pablo Picasso.
- Lo pintó _______representar las atrocidades de la guerra.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 5. Asia, Angie y Erica iban a dar un paseo __________el
- parque pero lo cancelaron _________el mal tiempo (bad weather)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- C.
-
-
-
-
-
-
-
-
-
-
-
-
- Pretérito e Imperfecto
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
- Gloria Fernández, the graduate student who spends many hours daily in front of the computer, wants to tell her friend Kathy about her visit to the doctor, so she sends her an e-mail. The main frame, however, is acting up, and some of the verbs have been deleted. Help Kathy complete the message by providing the missing verbs in the appropriate tense—either the preterite or the imperfect.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- correo_para_kathy@abc.edu
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Tema: Mi visita al doctor
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Querida Kathy:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Ayer fui al doctor porque no (sentirse) __________________
-
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- bien: me (doler) __________________
-
-
-
-
-
-
-
-
-
-
-
- 2
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- la cabeza y (tener) __________________
-
-
-
-
-
-
-
-
-
-
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- los ojos irritados. Primero, el doctor me (tomar)
- _______________
-
-
-
-
-
-
-
-
-
-
-
- 4
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- la temperatura, pero no (tener) ____________
-
-
-
-
-
-
-
-
-
-
-
- 5
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- fiebre. Después me (examinar) _______________
-
-
-
-
-
-
-
-
-
-
-
- 6
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- los ojos y me (preguntar) __________________
-
-
-
-
-
-
-
-
-
-
-
- 7
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- si (trabajar) __________________
-
-
-
-
-
-
-
-
-
-
-
- 8
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- mucho con la computadora; yo le (decir) __________________
-
-
-
-
-
-
-
-
-
-
-
-
- 9
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- que sí. Entonces él me (recomendar) __________________
-
-
-
-
-
-
-
-
-
-
-
-
- 10
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- que tomara
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- descansos y relajara
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- los ojos, porque las computadoras son malas para la vista.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- D.
-
-
-
-
-
-
-
-
-
-
-
-
- Unplanned/Unexpected Events
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Pamela is at work and her friend Susana arrives late. She has had a horrible morning. Pamela discusses Susana’s horrible morning with her coworkers during her lunch break.
-
-
-
-
-
-
-
-
-
-
- Following the model, use the cues and the verbs in parentheses to write complete sentences with
-
-
-
-
-
-
-
-
-
-
-
-
- se
-
-
-
-
-
-
-
-
-
-
- describing Susana’s actions.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- MODELO
-
-
-
-
-
-
-
-
-
-
- :
-
-
-
-
-
-
-
-
-
-
-
- When she tells them that Susana forgot her keys in her
- house, she says
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- (olvidar)
-
-
-
-
-
-
-
-
-
-
-
- A Susana se le olvidaron las llaves en su casa.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1.
-
-
-
-
-
-
-
-
-
-
-
- When she tells them that Susana lost her cellular phone,
- she says:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- (perder)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 2.
-
-
-
-
-
-
-
-
-
-
-
- When she tells them that Susana ‘s car ran out of gas she
- says:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- (acabar)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 3.
-
-
-
-
-
-
-
-
-
-
-
- When she tells them that Susana’s glasses broke, she says:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- (romper)_______________________________________________________________________
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 4.
-
-
-
-
-
-
-
-
-
-
-
- When she tells them that Susana left her documents at home,
- she says:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- (quedar)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 5.
-
-
-
-
-
-
-
-
-
-
-
- When she tells them that Susana dropped her coffee, she
- says:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- (caer)
- _________________________________________________________________________
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- E
-
-
-
-
-
-
-
-
-
-
-
-
- . Los Adverbios-
-
-
-
-
-
-
-
-
-
-
- Change the adjectives in parentheses to adverbs.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- La doctora le dice a Pablo que todo va a ir bien:
-
-
-
-
-
-
-
-
-
- —
-
-
-
-
-
-
-
-
-
-
- Señor Ortiz, su salud está
-
-
-
-
-
-
-
-
-
-
-
- (perfecto) ________________
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
-
-
-
- bien. Su peso está bajando (rápida) ________________
-
-
-
-
-
-
-
-
-
-
-
- 2
-
-
-
-
-
-
-
-
-
-
- de 220 libras a 180 y parece que hace ejercicios
- (frecuente) ________________
-
-
-
-
-
-
-
-
-
-
-
- 3.
-
-
-
-
-
-
-
-
-
-
- Necesita una dieta (total) ________________
-
-
-
-
-
-
-
-
-
-
-
- 4
-
-
-
-
-
-
-
-
-
-
- baja en grasas para mantener su peso. Además, quiero que
- escuche mis consejos (cuidadoso) ________________
-
-
-
-
-
-
-
-
-
-
-
- 5
-
-
-
-
-
-
-
-
-
-
- y espero que vaya a casa más (tranquilo)
-
-
-
-
-
-
-
-
-
-
- _______________________________.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/fetch_rss.php b/examples/fetch_rss.php
deleted file mode 100644
index 44767bc9..00000000
--- a/examples/fetch_rss.php
+++ /dev/null
@@ -1,45 +0,0 @@
-
- * @license LGPL The GNU Lesser GPL (LGPL) or an MIT-like license.
- */
-require_once '../src/QueryPath/QueryPath.php';
-
-// The URL of the remote RSS feed.
-$remote = 'http://querypath.org/aggregator/rss/2/rss.xml';
-
-// We will write the results into this document.
-$out = qp(QueryPath::HTML_STUB, 'title')
- ->text('RSS Titles')
- ->top()
- ->find('body')
- ->append('')
- ->children('ul');
-
-// Load the remote document and loop through all of the items.
-foreach (qp($remote, 'channel>item') as $item) {
- // Get title and link.
- $title = $item->find('title')->text();
- $link = $item->next('link')->text();
-
- // Do a little string building.
- $bullet = '' . $title . '';
-
- // Add it to the output document.
- $out->append($bullet);
-}
-
-// Write the results.
-$out->writeHTML();
diff --git a/examples/filtering-by-text-content/index.php b/examples/filtering-by-text-content/index.php
new file mode 100644
index 00000000..895f8ca6
--- /dev/null
+++ b/examples/filtering-by-text-content/index.php
@@ -0,0 +1,50 @@
+
+ * @license LGPL The GNU Lesser GPL (LGPL) or an MIT-like license.
+ */
+
+require_once __DIR__ . '/../../vendor/autoload.php';
+
+try {
+ $qp = html5qp('https://www.php.net');
+
+ echo 'Filtering Content
';
+ echo 'PHP Releases
';
+
+ /* Get any posts containing the word 'Release' */
+ echo $qp->find('h2.newstitle a:contains(Release)')
+ ->textImplode('
' . PHP_EOL);
+
+ echo 'PHP news in the past 30 days...
';
+
+ echo $qp->find('header.title')
+ ->filterCallback(function ($index, $item) {
+ /*
+ * Returns TRUE to keep current $item in matches, or FALSE to remove
+ *
+ * $item is a DOMNode (actually, a DOMElement). So if we wanted to do QueryPath
+ * manipulations on it, you can pass it to html5qp()
+ */
+
+ /* Get the current post datetime */
+ $datetime = new DateTimeImmutable(html5qp($item, 'time')->attr('datetime'));
+
+ /* Keep any posts less than 30 days old */
+ return $datetime > (new DateTimeImmutable('-30 days'));
+ })
+ ->find('a')
+ ->textImplode('
' . PHP_EOL);
+} catch (\QueryPath\Exception $e) {
+ die($e->getMessage());
+}
diff --git a/examples/html.php b/examples/html.php
deleted file mode 100644
index 199ef26d..00000000
--- a/examples/html.php
+++ /dev/null
@@ -1,56 +0,0 @@
-
- * @license LGPL The GNU Lesser GPL (LGPL) or an MIT-like license.
- */
-
-require_once '../src/qp.php';
-
-// Begin with an HTML stub document (XHTML, actually), and navigate to the title.
-qp(QueryPath::HTML_STUB, 'title')
- // Add some text to the title
- ->text('Example of QueryPath.')
- // Now look for the element
- ->top('body')
- // Inside the body, add a title and paragraph.
- ->append('This is a test page
Test text
')
- // Now we select the paragraph we just created inside the body
- ->children('p')
- // Add a 'class="some-class"' attribute to the paragraph
- ->attr('class', 'some-class')
- // And add a style attribute, too, setting the background color.
- ->css('background-color', '#eee')
- // Now go back to the paragraph again
- ->parent()
- // Before the paragraph and the title, add an empty table.
- ->prepend('')
- // Now let's go to the table...
- ->top('#my-table')
- // Add a couple of empty rows
- ->append('|
')
- // select the rows (both at once)
- ->children()
- // Add a CSS class to both rows
- ->addClass('table-row')
- // Now just get the first row (at position 0)
- ->eq(0)
- // Add a table header in the first row
- ->append('This is the header | ')
- // Now go to the next row
- ->next()
- // Add some data to this row
- ->append('This is the data | ')
- // Write it all out as HTML
- ->writeHTML();
diff --git a/examples/http-stream-xml-namespaces-and-linked-data/index.php b/examples/http-stream-xml-namespaces-and-linked-data/index.php
new file mode 100644
index 00000000..3cd3c128
--- /dev/null
+++ b/examples/http-stream-xml-namespaces-and-linked-data/index.php
@@ -0,0 +1,82 @@
+
+ * @license LGPL The GNU Lesser GPL (LGPL) or an MIT-like license.
+ * @see http://www.w3.org/DesignIssues/LinkedData.html
+ * @see http://dbpedia.org
+ * @see sparql.php
+ * @see musicbrainz.php
+ */
+
+require_once __DIR__ . '/../../vendor/autoload.php';
+
+// The URL to look up:
+$url = 'https://dbpedia.org/resource/Ben_Sealey';
+
+// HTTP headers:
+$headers = [
+ 'Accept: application/rdf,application/rdf+xml;q=0.9,*/*;q=0.8',
+ 'Accept-Language: en-us,en',
+ 'Accept-Charset: ISO-8859-1,utf-8',
+ 'User-Agent: QueryPath/1.2',
+];
+
+// The context options:
+$options = [
+ 'http' => [
+ 'method' => 'GET',
+ 'protocol_version' => 1.1,
+ 'header' => implode("\r\n", $headers),
+ ],
+];
+
+// Create a stream context that will tell QueryPath how to load the file.
+$context = stream_context_create($options);
+
+try {
+ // Fetch the URL and select all rdf:Description elements.
+ // (Note that | is the CSS 3 equiv of colons for namespacing.)
+ // To add the context, we pass it in as an option to QueryPath.
+ $qp = qp($url, 'rdf|Description', ['context' => $context]);
+
+ printf('There are %d descriptions in this record.
' . PHP_EOL, $qp->count());
+
+ // Here, we use foaf|* to select all elements in the FOAF namespace.
+ printf('There are %d DBO items in this record.
' . PHP_EOL, $qp->top()->find('dbo|*')->count());
+
+ // Standard pseudo-classes that are not HTML specific can be used on namespaced elements, too.
+ echo 'About (RDFS): ' . $qp->top()->find('rdfs|label:first-of-type')->text() . '
' . PHP_EOL;
+ echo 'About (FOAF): ' . $qp->top()->find('foaf|name:first-of-type')->text() . '
' . PHP_EOL;
+
+ // Namespaced attributes can be retrieved using the same sort of delimiting.
+ echo PHP_EOL . '
Comment:
' . PHP_EOL;
+ echo $qp->top()->find('rdfs|comment[xml|lang="en"]')->text();
+ echo '
' . PHP_EOL;
+
+ $qp->top();
+
+ echo PHP_EOL . '
Other Sites:
' . PHP_EOL;
+ foreach ($qp as $item) {
+ echo $item->attr('rdf:about') . '
' . PHP_EOL;
+ }
+} catch (\QueryPath\Exception $e) {
+ // Handle QueryPath exceptions
+ die($e->getMessage());
+}
diff --git a/examples/matching_text_content.php b/examples/matching_text_content.php
deleted file mode 100644
index 69891260..00000000
--- a/examples/matching_text_content.php
+++ /dev/null
@@ -1,51 +0,0 @@
-
- * @license LGPL The GNU Lesser GPL (LGPL) or an MIT-like license.
- */
-
-/** Include QueryPath. */
-require_once '../src/QueryPath/QueryPath.php';
-
-/**
- * Check if the string 'Release' is in the text content of any matched nodes.
- *
- * Returns TRUE if the text is found, FALSE otherwise. Anytime a filter callback
- * returns FALSE, QueryPath will remove it from the matches.
- *
- * Note that $item is a DOMNode (actually, a DOMElement). So if we wanted to do QueryPath
- * manipulations on it, we could wrap it in a `qp()`.
- */
-function exampleCallback($index, $item)
-{
- $text = qp($item)->text();
-
- return strpos($text, 'Release') !== false;
-}
-
-/*
- * This is the QueryPath call.
- *
- * First we fetch the remote page, parse it, and grab just the `a` tags inside of the summary.
- * Then we filter the results through our callback.
- * Finally, we fetch all of the matching text and print it.
- *
- * NOTE: If you are using PHP 5.3, you can define the callback inline instead of separating it
- * into a stand-alone function.
- */
-print htmlqp('http://php.net/', 'h1.summary a')
- ->filterCallback('exampleCallback')
- ->textImplode(PHP_EOL);
diff --git a/examples/musicbrainz.php b/examples/musicbrainz.php
deleted file mode 100644
index 480bf998..00000000
--- a/examples/musicbrainz.php
+++ /dev/null
@@ -1,40 +0,0 @@
-
- * @license LGPL The GNU Lesser GPL (LGPL) or an MIT-like license.
- * @see http://musicbrainz.org
- */
-require_once '../src/QueryPath/QueryPath.php';
-
-$artist_url = 'http://musicbrainz.org/ws/1/artist/?type=xml&name=u2';
-$album_url = 'http://musicbrainz.org/ws/1/release/?type=xml&artistid=';
-try {
- $artist = qp($artist_url, 'artist:first');
- if ($artist->size() > 0) {
- $id = $artist->attr('id');
- print 'The best match we found was for ' . $artist->children('name')->text() . PHP_EOL;
- print '
Artist ID: ' . $id . PHP_EOL;
- print '
Albums for this artist' . PHP_EOL;
- print '
' . $album_url . '
';
- $albums = qp($album_url . urlencode($id))->writeXML();
-
- foreach ($albums as $album) {
- print $album->find('title')->text() . PHP_EOL;
- // Fixme: Label is broken. See Drupal QueryPath module.
- print '(' . $album->next('label')->text() . ')' . PHP_EOL;
- }
- }
-} catch (Exception $e) {
- print $e->getMessage();
-}
diff --git a/examples/odt.php b/examples/odt.php
index 1028e494..6a6ad2d1 100644
--- a/examples/odt.php
+++ b/examples/odt.php
@@ -18,7 +18,7 @@
*/
/** Include main QP library. */
-require_once '../src/QueryPath/QueryPath.php';
+require_once __DIR__ . '/../vendor/autoload.php';
// If you have the Zip lib combiled in:
//$file = 'zip://openoffice.odt#content';
diff --git a/examples/openoffice.odt b/examples/openoffice.odt
index 69632f53..e69de29b 100644
Binary files a/examples/openoffice.odt and b/examples/openoffice.odt differ
diff --git a/examples/parse_php.php b/examples/parse_php.php
index c2b6dc6e..bb39506a 100644
--- a/examples/parse_php.php
+++ b/examples/parse_php.php
@@ -14,6 +14,8 @@
* @author M Butcher
* @license LGPL The GNU Lesser GPL (LGPL) or an MIT-like license.
*/
+
+require_once __DIR__ . '/../vendor/autoload.php';
?>
@@ -21,8 +23,6 @@
text();
?>
diff --git a/examples/parsing-rss-feed/index.php b/examples/parsing-rss-feed/index.php
new file mode 100644
index 00000000..a0adea93
--- /dev/null
+++ b/examples/parsing-rss-feed/index.php
@@ -0,0 +1,51 @@
+
+ * @license LGPL The GNU Lesser GPL (LGPL) or an MIT-like license.
+ */
+require_once __DIR__ . '/../../vendor/autoload.php';
+
+// The URL of the remote RSS feed.
+$remote = 'https://en.wikipedia.org/w/index.php?title=Special:NewPages&feed=rss';
+
+try {
+ // We will write the results into this document.
+ $qp = html5qp(\QueryPath\QueryPath::HTML5_STUB, 'title')
+ ->text('New Wikipedia Pages')
+ ->top('body')
+ ->append('New Wikipedia Pages
')
+ ->append('')
+ ->children('ul');
+
+ // Load the remote document and loop through all the items.
+ foreach (qp($remote, 'channel>item') as $item) {
+ // Get title and link.
+ $title = $item->find('title')->text();
+ $link = $item->find('link')->text();
+
+ $list = html5qp('', 'li')
+ ->append('')
+ ->find('a')
+ ->attr('href', $link)
+ ->text($title);
+
+ // Add it to the output document.
+ $qp->append($list->top()->innerHTML5());
+ }
+
+ // Write the results.
+ $qp->writeHTML5();
+} catch (Exception $e) {
+ die($e->getMessage());
+}
diff --git a/examples/parsing-xml-from-url-and-dynamically-generating-html/index.php b/examples/parsing-xml-from-url-and-dynamically-generating-html/index.php
new file mode 100644
index 00000000..6ca1b7e0
--- /dev/null
+++ b/examples/parsing-xml-from-url-and-dynamically-generating-html/index.php
@@ -0,0 +1,94 @@
+' . htmlentities($name) . '
';
+}
+
+try {
+ // The document skeleton
+ $qp = html5qp(__DIR__ . '/template.html', 'body');
+
+ $key = $_GET['key'] ?? '';
+
+ // Only display jQuery methods from these categories
+ $categories = [
+ 'traversing/tree-traversal' => 'Tree Traversal',
+ 'selectors/child-filter-selectors' => 'Child Filter',
+ 'selectors/attribute-selectors' => 'Attribute',
+ 'selectors/content-filter-selector' => 'Content Filter',
+ 'selectors/basic-filter-selectors' => 'Basic Filter',
+ 'selectors/hierarchy-selectors' => 'Hierarchy',
+ 'selectors/basic-css-selectors' => 'Basic',
+ 'traversing/filtering' => 'Filtering',
+ 'traversing/miscellaneous-traversal' => 'Miscellaneous Traversing',
+ 'manipulation/dom-insertion-outside' => 'DOM Insertion, Outside',
+ 'manipulation/dom-insertion-inside' => 'DOM Insertion, Inside',
+ 'manipulation/style-properties' => 'Style Properties',
+ ];
+
+ $jquery = [];
+
+
+ // Search through the xml file to find all entries of jQuery entities
+ foreach (qp('https://api.jquery.com/resources/api.xml', 'entry') as $entry) {
+ foreach ($entry->find('category') as $item) {
+ $category = $categories[$item->attr('slug')] ?? '';
+ if ($category) {
+ $jquery[$entry->attr('name')] = [
+ 'longdesc' => $entry->find('longdesc')->innerXML(),
+ 'name' => sprintf('%s: %s', $category, $entry->attr('name')),
+ ];
+
+ break;
+ }
+ }
+ }
+
+ // Map the keys & sort them
+ $jqueryKeys = array_keys($jquery);
+ sort($jqueryKeys);
+
+ $links = array_map('addClasses', $jqueryKeys);
+ // Add the keys to the nav bar
+ $sidebar = $qp->find('#leftbody');
+ foreach ($links as $link) {
+ $sidebar->append($link);
+ }
+
+ // Add the description to the main window if the key exists
+ $key = isset($jquery[$key]) ? $key : $jqueryKeys[0];
+
+ $qp->top()->find('#rightfunction')->text('Function: ' . ucfirst($key));
+ $qp->top()->find('#rightdesc')->remove();
+ $qp->top()->find('#righttitle')->text('jQuery Documentation');
+ $qp->top()->find('#righttext')->append($jquery[$key]['longdesc']);
+
+ $qp->top()->find('#current-year')->text(date('Y'));
+
+ // Write the document
+ $qp->writeHTML5();
+} catch (\QueryPath\Exception $e) {
+ // Handle QueryPath exceptions
+ die($e->getMessage());
+}
diff --git a/examples/parsing-xml-from-url-and-dynamically-generating-html/template.html b/examples/parsing-xml-from-url-and-dynamically-generating-html/template.html
new file mode 100644
index 00000000..5a06fc4e
--- /dev/null
+++ b/examples/parsing-xml-from-url-and-dynamically-generating-html/template.html
@@ -0,0 +1,111 @@
+
+
+
+
+ Example: Parsing XML from a URL and inserting into a HTML Template File
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/querypath.xml b/examples/querypath.xml
deleted file mode 100644
index f16e4beb..00000000
--- a/examples/querypath.xml
+++ /dev/null
@@ -1,236 +0,0 @@
-
-
-
-
- Add constructs a new element at the specified location in the document.
-
-
-
-
- - list item 1
- - list item 2
- - list item 3
-
- a paragraph
-
- $('li').add('new paragraph
')
- .css('background-color', 'red');
-
-
-
- test.html
-
-
-
-
- Hello
- Hello Again
-
-
-
-
- test.php
-
- require_once 'QueryPath.php';
-
- htmlqp('test.html')
- $qp->append('new paragraph
')
- ->find('p')
- ->css('background-color', 'red')
- ->top()
- ->writeXHTML();
-
-
-
-
-
- It's important to note that this method does not replace a class. It simply adds the class, appending it to any which may already be assigned to the elements.
-
- More than one class may be added at a time, separated by a space, to the set of matched elements.
-
-
- This method is often used with .removeClass() to switch elements' classes from one to another.
-
- $('p').addClass('myClass yourClass');
-
- $('p').removeClass('myClass noClass').addClass('yourClass');
-
- $('ul li:last').addClass(function() {
- return 'item-' + $(this).index();
- });
-
- Given an unordered list with five li elements, this example adds the class "item-4" to the last li.
-
-
- test.html
-
-
-
-
- Hello
- Hello Again
-
-
-
-
- test.php
-
- require_once 'QueryPath.php';
-
- htmlqp('test.html')
- $qp->append('')
- ->find('div')
- ->addClass('testing one two three')
- ->top()
- ->writeXHTML();
-
-
-
-
-
- The selector expression preceding the method is the container after which the content is inserted.
-
-
- This method is often used with .removeClass() to switch elements' classes from one to another.
-
-
-
Greetings
-
Hello
-
Goodbye
-
- We can create content and insert it after several elements at once:
- $('.inner').after('Test
');
- We can also select an element on the page and insert it after another:
- $('.container').after($('h2'));
- .after() will also work on disconnected DOM nodes. For example, given the following code:
- $('').after('');
-
-
-
- test.html
-
-
-
-
- Hello
- Hello Again
-
-
-
-
- test.php
-
- require_once 'QueryPath.php';
-
- htmlqp('test.html')
- $qp->append('First P
Second P
')
- ->children('p')
- ->after('new paragraph
')
- ->top()
- ->writeHTML();
-
-
-
-
-
-
-
-
-
-
-
Greetings
-
Hello
-
Goodbye
-
-
-
-
- test.html
-
-
-
-
- Hello
- Hello Again
-
-
-
-
- test.php
-
- require_once 'QueryPath.php';
-
- htmlqp('test.html')
- $qp->append('First P
Second P
')
- ->children('p')
- ->after('new paragraph
')
- ->top()
- ->writeHTML();
-
-
-
-
-
- Add a yellow background to a span and to all of the children of an element.
-
-
-
-
-
-
-
-
-
- Hello
- Hello Again
-
-
-
-
-
-
- test.html
-
-
-
-
- Hello
- Hello Again
-
-
-
-
- test.php
-
- require_once 'QueryPath.php';
-
- htmlqp('test.html')
- ->find('span') // Point querypath to the span
- ->css('background', 'yellow') // Add the CSS
- ->top() // Point QueryPath to the top of the page
- ->writeXHTML(); // Write HTML, notice it does not use print
-
-
-
-
\ No newline at end of file
diff --git a/examples/remote-filter-and-retrieval/index.php b/examples/remote-filter-and-retrieval/index.php
new file mode 100644
index 00000000..2842e0c3
--- /dev/null
+++ b/examples/remote-filter-and-retrieval/index.php
@@ -0,0 +1,43 @@
+Urban Dictionary Random Word Generator';
+
+try {
+ $page = random_int(0, 288);
+ $word = random_int(0, 7);
+
+ // Load a random page from the Urban Dictionary
+ $qp = html5qp('https://www.urbandictionary.com/?page=' . $page);
+
+ // Select a random word/definition out of the 7 shown on the loaded page
+ // Get the Word
+ printf(
+ 'Word: %s
',
+ $qp->find('.word')
+ ->eq($word)
+ ->text()
+ );
+
+ $qp->top();
+
+ // Get the definition
+ echo 'Definition: ' .
+ $qp->find('.meaning')
+ ->eq($word)
+ ->text();
+} catch (\QueryPath\Exception $e) {
+ // Handle QueryPath exceptions
+ die($e->getMessage());
+} catch (Exception $e) {
+ // Handle the random_int() exception
+ die($e->getMessage());
+}
diff --git a/examples/simple_example.php b/examples/simple_example.php
index 61c31d8f..1474727d 100644
--- a/examples/simple_example.php
+++ b/examples/simple_example.php
@@ -22,7 +22,9 @@
* @see html.php
* @see https://fedorahosted.org/querypath/wiki/QueryPathTutorial The Official Tutorial
*/
-require_once '../src/QueryPath/QueryPath.php';
+
+require_once __DIR__ . '/../vendor/autoload.php';
+
qp(QueryPath::HTML_STUB)->find('body')->text('Hello World')->writeHTML();
$qp = htmlqp(QueryPath::HTML_STUB, 'body');
diff --git a/examples/sparql.php b/examples/sparql.php
index b8dcceb0..ef73ab9c 100644
--- a/examples/sparql.php
+++ b/examples/sparql.php
@@ -20,7 +20,7 @@
* @see http://drupal.org/project/querypath
*/
-require '../src/QueryPath/QueryPath.php';
+require_once __DIR__ . '/../vendor/autoload.php';
// We are using the dbpedia database to execute a SPARQL query.
diff --git a/examples/svg.php b/examples/svg.php
index 23e655a3..d173318a 100644
--- a/examples/svg.php
+++ b/examples/svg.php
@@ -16,7 +16,7 @@
* @license LGPL The GNU Lesser GPL (LGPL) or an MIT-like license.
*/
-require_once '../src/QueryPath/QueryPath.php';
+require_once __DIR__ . '/../vendor/autoload.php';
// Let's stub out a basic SVG document.
$svg_stub = '
diff --git a/examples/techniques.php b/examples/techniques.php
index e47f5ddb..19f7cefd 100644
--- a/examples/techniques.php
+++ b/examples/techniques.php
@@ -19,7 +19,7 @@
* @license LGPL (The GNU Lesser GPL) or an MIT-like license.
*/
-require '../src/QueryPath/QueryPath.php';
+require_once __DIR__ . '/../vendor/autoload.php';
$demo = '
diff --git a/examples/xml.php b/examples/xml.php
deleted file mode 100644
index 1293f29b..00000000
--- a/examples/xml.php
+++ /dev/null
@@ -1,55 +0,0 @@
-
- * xml version="1.0"?>
- *
- * (A space was inserted above to prevent the documentation renderer from
- * misinterpreting it.)
- *
- * @author M Butcher
- * @license LGPL The GNU Lesser GPL (LGPL) or an MIT-like license.
- */
-
-require_once '../src/QueryPath/QueryPath.php';
-
-
-// Create a new XML document wrapped in a QueryPath.
-// By default, it will point to the root element,
-//
-$record = qp('')
- // Add a new last name inside of author.
- ->append('Dostoyevsky')
- // Select all of the children of . In this case,
- // that is
- ->children()
- // Oh, wait... we wanted last name to be inside of a
- // element. Use wrap to wrap the current element in something:
- ->wrap('')
- // And before last name, we want to add first name.
- ->before('')
- // Select first name
- ->prev()
- // Set the text of first name
- ->text('Fyodor')
- // And then after first name, add the patronymic
- ->after('Fyodorovich')
- // Now go back to the root element, the top of the document.
- ->top()
- // Add another tag -- origin.
- ->append('Russia')
- // turn the QueryPath contents back into a string. Since we are
- // at the top of the document, the whole document will be converted
- // to a string.
- ->xml();
-
-// Print our results.
-print $record;
diff --git a/src/DOMQuery.php b/src/DOMQuery.php
index ae6ace88..8231fa18 100644
--- a/src/DOMQuery.php
+++ b/src/DOMQuery.php
@@ -1216,8 +1216,8 @@ public function xhtml($markup = null)
* In getter mode, the first element wrapped by this DOMNode object will be
* converted to an XML string and returned.
*
- * @param string|null $markup
- * A string containing XML data.
+ * @param string|true|null $markup
+ * A string containing XML data. If true is passed, the XML declaration will be omitted.
*
* @return DOMQuery|string|null
* If markup is passed in, a DOMQuery is returned. If no markup is passed
@@ -1594,7 +1594,7 @@ public function __call($name, $arguments)
/**
* Get an iterator for the matches in this object.
*
- * @return Traversable
+ * @return Traversable
* Returns an iterator.
*/
public function getIterator(): Traversable