Skip to content

remove() and replaceAll() throw "Unknown Pseudo-Class: matches" for :matches() #123

Closed

Description

@gravitypdf-bot

Description of the bug

The legacy selector engine, QueryPath\CSS\QueryPathEventHandler, does not recognise :matches(). It is still the engine behind remove() and replaceAll(), so those methods throw on a selector that find() accepts:

$xml = '<?xml version="1.0"?><ul><li id="a"/><li id="b" class="x"/><li id="c"/></ul>';

qp($xml)->find('li:matches(.x)');    // b
qp($xml)->remove('li:matches(.x)');  // QueryPath\CSS\ParseException: Unknown Pseudo-Class: matches

The exception is raised by the default branch of the pseudo-class switch in QueryPathEventHandler (src/CSS/QueryPathEventHandler.php, around line 637). CSS\DOMTraverser supports :matches(), so the two engines disagree.

Suggested fix

Add a matches case alongside not and has. :matches(X) keeps the candidates that match X, the complement of :not(X), so it can share that implementation. Worth considering :is() (the CSS Selectors 4 name for :matches()) at the same time, in both engines.

QueryPath version

main at b41810e. Found while working on #120 / #122.

PHP Version and environment

PHP 8.5 CLI (macOS). Not version-specific.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions