Repository navigation
🐛 fix(convert): css_to_xpath empty value with i flag - #1086
Merged
Merged
Conversation
gaborbernat
force-pushed
the
fix/css-xpath-empty-i
branch
from
October 3, 2026 10:03
60f7c7b to
ab8ab59
Compare
Merging this PR will not alter performance
Comparing Footnotes
|
gaborbernat
added a commit
that referenced
this pull request
Oct 3, 2026
`css_to_xpath` translated `[att|="" i]`, and `p[lang|=""]` through HTML's [case-insensitive attribute list](https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors), into `translate(@att, ...) = '' or starts-with(...)`. [`string()` of an empty node-set](https://www.w3.org/TR/1999/REC-xpath-19991116/#function-string) is the empty string, so the expression also matched elements without the attribute, while [Selectors 4](https://www.w3.org/TR/selectors-4/#attribute-representation) matches `[att|=val]` only on elements that have `att`. The translation now requires the attribute before comparing its folded empty value, the guard #1086 added for `=`. A non-empty `|=` value never matches an empty string, and `^=`, `$=`, `*=` and `~=` already translate an empty value to `false()`, so the other cases keep their output. On `<div><p id=none></p><p id=empty d=""></p><p id=dash d="-x"></p></div>`, the XPath for `[d|="" i]` on lxml 6.1.3 now selects `empty` and `dash`, the same elements as `select()`. [cssselect 1.5.0](https://github.com/scrapy/cssselect/blob/v1.5.0/cssselect/xpath.py#L794-L804) wraps every `|=` match in the same presence guard, and it rejects the `i` flag with a syntax error. closes #1109
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
css_to_xpathtranslated an attribute selector with an empty value and theiflag, such as[d="" i], intotranslate(@d, ...) = '', which also matches elements without the attribute becausetranslate()of an absent attribute is the empty string.The translation now requires the attribute before comparing its folded value, since XPath 1.0 turns an empty node-set into the empty string that
translate()then returns, while Selectors 4 matches[att=val]only on elements that haveatt, and itsiflag changes only how the value compares. It now selects the same elements asselect().Neither cssselect 1.5.0 nor css-to-xpath 0.1.0 parses the
iflag; both raise a syntax error on[d="" i].closes #1040