symfony: CSSSelector breaks on DOMDocument containing HTML elements with namespaces

PHPPowertools/DOM-Query is the first component of the PHPPowertools framework that has been released to the public. It’s purpose is similar to that of technosophos/querypath but it’s implementation is far more true to both jQuery’s syntax and its semantics. For example, PHPPowertools/DOM-Query lets you do stuff like this :

// Add a span tag with classes 'icon' and 'icon-printer' to all buttons
$H->select('body')->select('button')->add('span')->addClass('icon icon-printer');

// Use a lambda function to set the data-val attribute of all gallery images
$H->select('.gallery li img')->attr('data-val', function( $i, $val) {
    return $i . " - " . $val->attr('class') . " - photo by Kelly Clark";
});

Under the hood, it uses symfony/CssSelector for converting _CSS selectors_ to _XPath queries_

What was still lacking until today, is proper support for HTML5. This has been solved by using Masterminds/html5-php’s HTML loading and saving instead of native DOMDocument loading.

To allow Masterminds/html5-php and symfony/CssSelector to play well together, I needed to modify Masterminds/html5-php to prevent HTML elements from being generated with the http://www.w3.org/1999/xhtml namespace as the selectors generated by symfony/CssSelector failed to do their job.

Is support of namespaced HTML elements a missing feature in this component or is this merely an option that I overlooked?


See also https://github.com/PHPPowertools/DOM-Query/issues/1 and https://github.com/Masterminds/html5-php/issues/67.

About this issue

  • Original URL
  • State: closed
  • Created 10 years ago
  • Comments: 21 (14 by maintainers)

Most upvoted comments

html5-php doesn’t really load that document. $dom->saveHTML(); returns an empty string.

Could you perhaps share your code? It’s hard to see what’s wrong without testing it myself.

Are you using the patched version of html5-php from my repo? The pull request that I submitted to the official repo hasn’t been merged yet and is required for the code to work.

Anyway, the following code should also work with the official html5-php release.

<?php
require __DIR__.'/vendor/autoload.php';

use Masterminds\HTML5;
use Symfony\Component\CssSelector\CssSelector;

$html = new HTML5(); // Create an instance of the HTML5 parser
$dom = $html->loadHTML(get_file_contents('http://www.cascade-framework.com/')); // Load content

$expression = CssSelector::toXPath('.highlights .cell'); // Parse selector
$xpath = new DOMXpath($dom); // Create query object
$elements = $xpath->query($expression); // Execute query
echo $html->saveHTML($dom); // Save the document to string and print it
echo $html->saveHTML($elements); // Save the elements to string and print them