Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Propose several CSS Selector style shorthands (first-child, last-child, etc.) #19

Open
rhdunn opened this issue Apr 6, 2020 · 3 comments

Comments

@rhdunn
Copy link

rhdunn commented Apr 6, 2020

I've found myself wanting to write XPath expressions equivalent or similar to the CSS E:first-child selector. The two use cases I have so far is:

  1. first child element is a given element -- child::*[1]/self::element-name;
  2. first child node is a text node -- child::node()[1]/self::text().

These are harder to read in XPath as they are spanning multiple steps, so having shorthand selectors for these could be useful.

NOTE: I don't have any concrete proposals for this.

Using first-child::element-name and first-child::text() would be easier to read. The former is CSS-like (match elements only), while the latter is XPath-like (match any nodes). Using different context behaviour would be confusing, and inconsistent with the other XPath axis selectors. It would also prevent supporting a child::node()[1]/self::element-name equivalent.

Another possibility would be to create two separate axes, such as first-child and first-child-element. This would be consistent with axes like ancestor/ancestor-or-self, but could quickly increase the number of axes. This version would add at least 4 new axes:

  1. first-child:: (forward);
  2. first-child-element:: (forward);
  3. last-child:: (reverse);
  4. last-child-element:: (reverse).

NOTE: Only the tree traversal CSS selectors would be applicable. CSS selectors like E:hover require context information that is not available, nor relevant to XPath.

Reference: https://drafts.csswg.org/selectors-4/#overview

@michaelhkay
Copy link
Member

michaelhkay commented Apr 6, 2020 via email

@rhdunn
Copy link
Author

rhdunn commented Apr 6, 2020

I agree w.r.t. orthogonality.

Your proposed syntax (which I like) would work differently for the first example. There, it is matching the first element child (not general node) if it has the specified name, so would ignore text/comment nodes.

That is, it would sometimes be useful to apply axes on elements only instead of all children.

@liamquin
Copy link

i often see people leave out the * before a predictate, /a/b/[last()]orwhatever (meaning the last "b" element, or perhaps meaning the last child of b. So making it legal would turn a syntax error into a legal but potentially wrong expression.

Is *[1][self::span] so hard? Since child is the default we can already omit that part.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants