Skip to content

[Proposal]: Introduce DOMElementSibling #2012

@stloyd

Description

@stloyd

Describe the Proposal

DOM elements/nodes contain information about their siblings, it is useful for scraping when details are located in the same element but don't have anything unique to extract them individually.

I.e:

<div>
    <span>foo</span>
    bar
</div>

To get span, we do:

ref('details')->htmlQuerySelector('div span'))->domElementValue()->trim()

However, we are unable to get the text after the span.

API Adjustments

final class DOMElementSibling extends ScalarFunctionChain
{
    public function __construct(
        private readonly ScalarFunction|\DOMNode|HTMLElement $node,
    ) {
    }

    public function eval(Row $row, FlowContext $context) : mixed
    {
        $types = [
            type_instance_of(\DOMNode::class),
        ];

        if (\class_exists('\Dom\HTMLElement')) {
            $types[] = type_instance_of(HTMLElement::class);
        }

        $node = (new Parameter($this->node))->as($row, $context, ...$types);

        if ($node instanceof \DOMDocument) {
            $node = $node->documentElement;
        }

        if ($node instanceof \DOMElement) {
            return $node->nextSibling;
        }

        if ($node instanceof HTMLElement) {
            return $node->nextSibling;
        }

        return null;
    }
}

And call:

ref('details')->htmlQuerySelector('div span'))->domElementSibling()->domElementValue()->trim()

Are you intending to also work on proposed change?

Yes

Are you interested in sponsoring this change?

None

Integration & Dependencies

No response

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions