XPath is not particularly well adapted to this kind of task, but contrary to what's been put forth in the comments it is possible using evaluate()
and some nested string functions like substring-before()
and substring-after()
:
$html = '
<html>
<head>
<style>
a span{
background-color: #ddd;
color: #21d;
}
</style>
</head>
<body>
<a href="test.html">this is a <span>test</span></a>
</body>
</html>
';
$dom = new DOMDocument();
$dom->loadHTML($html);
$xpath = new DomXPath($dom);
$result = $xpath->evaluate("
substring-before(
substring-after(
substring-after(
normalize-space(//style/text())
, 'a span')
,' color:')
,';')
");
echo $result;
OUTPUT:
#21d
Working from the inside out:
- Normalize whitespace.
- Get the part of the style text after your selector.
- Get the text after the css rule in question. Notice I added a space before
' color:'
to avoid possibly getting background-color
or the like. Normalizing the space in step one makes this work even if color:
was preceded by a tab.
- get the string before the final
;
of the color
rule.
I'm pretty sure there are a slew of potential points of failure here and I wouldn't recommend using XPath for something like this but it's an interesting exercise all the same.