Reputation: 57176
How can I get the width and height of each element's attribute?
For instance,
$dom = new DOMDocument;
$dom->loadHTML('<div class="item" style="width:295px; height:210px; border:1px solid #000;"></div><div></div>');
foreach( $dom->getElementsByTagName('div') as $node )
{
$style = $node->getAttribute( 'style' );
var_dump($style);
}
result,
string 'width:295px; height:210px; border:1px solid #000;' (length=49)
string '' (length=0)
but these are what I am after,
div
that has the classname of item
only.295
(width) and 210
(height) only.Is it possible with DOM? Or XPATH?
EDIT:
I seem to manage to select the div with the classname now,
$dom = new DOMDocument;
$dom->loadHTML('<div class="item" style="width:295px; height:210px; border:1px solid #000;"></div><div></div>');
$xpath = new DOMXpath($dom);
foreach ($xpath->query('//*[@class="item"]') as $node) {
$style = $node->getAttribute( 'style' );
var_dump($style);
}
Now this is what I am after only,
get 295
(width) and 210
(height).
Upvotes: 2
Views: 6706
Reputation: 47894
Style properties, as I recall, are "kebab-cased" -- IOW, they are expected to be all lowercase and all words are separated by hyphens. Here's one resource.
You have demonstrated a good choice by using a DOM parser to target your div
elements with the item
class.
The next step of parsing the style declarations would, again, be most reliable with a CSS Parser, but if you are not interested in going to that effort, then a couple of preg_match()
calls with discerning patterns should keep you in good stead.
For those who are not aware of fringe cases that may monkeywrench the outcomes for this task, I am adding a title
attribute to one of the divs that will fool an inadequate pattern or DOM-unaware technique, and also adding a line-height
declaration for the same reason. These samples will catch many of the possible "shortcut" solutions that fail to parse the DOM.
The regex pattern must match the whole words height
and width
. My pattern will check that these words are at the start of the string or are preceded by a semicolon then zero or more whitespace characters. Once one of the words is found, the next non-whitesoace character must be a colon. Then after allowing zero or more whitespace characters again, I use \K
to "forget" all previously matched characters, then ONLY return the desired digital characters as the "full string match" (element [0]
).
Code: (Demo)
$html = <<<HTML
<div class="items">
<div class="item" title="Checking for bad parsing. height:666px; width:666px;" style="width:295px; height:210px; border:1px solid #000;"></div>
<div></div>
<div class="item" style="line-height:14pt; border:1px solid #000; height :420px; width: 590px;"></div>
</div>
HTML;
$dom = new DOMDocument;
$dom->loadHTML($html);
$xpath = new DOMXpath($dom);
foreach ($xpath->query('//div[@class="item"]/@style') as $node) {
$style = $node->nodeValue;
echo "The height integer: " , preg_match('~(?:^|;)\s*height\s*:\s*\K\d+~', $style, $h) ? $h[0] : '';
echo "\n";
echo "The width integer: " , preg_match('~(?:^|;)\s*width\s*:\s*\K\d+~', $style, $w) ? $w[0] : '';
echo "\n---\n";
}
Output:
The height integer: 210
The width integer: 295
---
The height integer: 420
The width integer: 590
---
Upvotes: 2
Reputation: 13
function GetStyleValue($style, $type){
$value = false;
$all = explode(';',$style);
foreach($all as $part){
$temp = explode(':', $part);
if(trim($temp[0]) == $type){
$value = (int)trim($temp[1]);
}
}
return $value;}
You can use this function to get width
, height
or other style value, just call:
$width = GetStyleValue($img->getAttribute("style"), 'width');
Upvotes: 1
Reputation: 59699
If you don't want to use a regex, you can use simple string functions to extract what you need. Here is an example, it most likely can be improved upon.
$width = 'width:'; $height = 'height:';
// Adding whitespace will not affect the result
$str = ' width: 295 px; height: 210 px; border:1px solid #000;';
$width_str = strstr( $str, $width);
echo 'Width: "' . trim( substr( $width_str, strlen( $width), stripos( $width_str, 'px;') - strlen( $width))) . '"';
echo "\n";
$height_str = strstr( $str, $height);
echo 'Height: "' . trim( substr( $height_str, strlen( $height), stripos( $height_str, 'px;') - strlen( $height))) . '"';
Of course, you can replace the $width
and $height
variables with their string literals, and remove the calls to strlen()
as they would be constant integers.
Upvotes: 1