For a system I am building I am defining a general style stored in LINKSTYLE that should be applied to a elements that are not yet sty
I was wondering if it's possible to solve this more CCS-wise, e.g. with a selector. In CSS3 it's possible to only address those tags that don't have the style attribute:
a:not([style]) {border:1px solid #000;}
So if your documents already have a stylesheet it could be easily added.
If not, then a must be added to the document. This can be done with DomDocument as well but I found it a bit complicated. However I got it to work for some little play:
libxml_use_internal_errors(true);
$html = 'test'.
'test2';
$dom = new DOMDocument();
$dom->loadHtml($html);
$dom->normalizeDocument();
// ensure that there is a head element, body will always be there
// because of loadHtml();
$head = $dom->getElementsByTagName('head');
if (0 == $head->length) {
$head = $dom->createElement('head');
$body = $dom->getElementsByTagName('body')->item(0);
$head = $body->parentNode->insertBefore($head, $body);
} else {
$head=$head->item(0);
}
// append style tag to head.
$css = 'a:not([style]) {border:1px solid #000;}';
$style = $dom->createElement('style');
$style->nodeValue=$css;
$head->appendChild($style);
$dom->formatOutput = true;
$output = $dom->saveHtml();
echo $output;
Example output:
testtest2
If the CSS clashes with other, higher selectors, this is not an easy solution. !important might help though.
And as far of getting the changed HTML fragment, this is some additional code that can work with gordons suggestion. Just the inner-html of the body tag, this time I played a bit with the SPL:
// get html fragment
$output = implode('', array_map(
function($node) use ($dom) { return $dom->saveXml($node); },
iterator_to_array($xpath->query('//body/*'), false)))
;
A foreach is definitely more readable and memory friendly:
// get html fragment
$output = '';
foreach($xpath->query('//body/*') as $node)
$output .= $dom->saveXml($node)
;