CARVIEW |
Select Language
HTTP/2 302
date: Wed, 23 Jul 2025 01:24:38 GMT
content-type: text/html; charset=utf-8
content-length: 0
vary: X-PJAX, X-PJAX-Container, Turbo-Visit, Turbo-Frame, X-Requested-With,Accept-Encoding, Accept, X-Requested-With
location: https://gist.github.com/HughxDev/3320053
cache-control: no-cache
strict-transport-security: max-age=31536000; includeSubdomains; preload
x-frame-options: deny
x-content-type-options: nosniff
x-xss-protection: 0
referrer-policy: origin-when-cross-origin, strict-origin-when-cross-origin
content-security-policy: default-src 'none'; base-uri 'self'; child-src github.githubassets.com github.com/assets-cdn/worker/ github.com/assets/ gist.github.com/assets-cdn/worker/; connect-src 'self' uploads.github.com www.githubstatus.com collector.github.com raw.githubusercontent.com api.github.com github-cloud.s3.amazonaws.com github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com github-production-user-asset-6210df.s3.amazonaws.com *.rel.tunnels.api.visualstudio.com wss://*.rel.tunnels.api.visualstudio.com objects-origin.githubusercontent.com copilot-proxy.githubusercontent.com proxy.individual.githubcopilot.com proxy.business.githubcopilot.com proxy.enterprise.githubcopilot.com *.actions.githubusercontent.com wss://*.actions.githubusercontent.com productionresultssa0.blob.core.windows.net/ productionresultssa1.blob.core.windows.net/ productionresultssa2.blob.core.windows.net/ productionresultssa3.blob.core.windows.net/ productionresultssa4.blob.core.windows.net/ productionresultssa5.blob.core.windows.net/ productionresultssa6.blob.core.windows.net/ productionresultssa7.blob.core.windows.net/ productionresultssa8.blob.core.windows.net/ productionresultssa9.blob.core.windows.net/ productionresultssa10.blob.core.windows.net/ productionresultssa11.blob.core.windows.net/ productionresultssa12.blob.core.windows.net/ productionresultssa13.blob.core.windows.net/ productionresultssa14.blob.core.windows.net/ productionresultssa15.blob.core.windows.net/ productionresultssa16.blob.core.windows.net/ productionresultssa17.blob.core.windows.net/ productionresultssa18.blob.core.windows.net/ productionresultssa19.blob.core.windows.net/ github-production-repository-image-32fea6.s3.amazonaws.com github-production-release-asset-2e65be.s3.amazonaws.com insights.github.com wss://alive.github.com api.githubcopilot.com api.individual.githubcopilot.com api.business.githubcopilot.com api.enterprise.githubcopilot.com; font-src github.githubassets.com; form-action 'self' github.com gist.github.com copilot-workspace.githubnext.com objects-origin.githubusercontent.com; frame-ancestors 'none'; frame-src viewscreen.githubusercontent.com notebooks.githubusercontent.com; img-src 'self' data: blob: github.githubassets.com media.githubusercontent.com camo.githubusercontent.com identicons.github.com avatars.githubusercontent.com private-avatars.githubusercontent.com github-cloud.s3.amazonaws.com objects.githubusercontent.com release-assets.githubusercontent.com secured-user-images.githubusercontent.com/ user-images.githubusercontent.com/ private-user-images.githubusercontent.com opengraph.githubassets.com copilotprodattachments.blob.core.windows.net/github-production-copilot-attachments/ github-production-user-asset-6210df.s3.amazonaws.com customer-stories-feed.github.com spotlights-feed.github.com objects-origin.githubusercontent.com *.githubusercontent.com; manifest-src 'self'; media-src github.com user-images.githubusercontent.com/ secured-user-images.githubusercontent.com/ private-user-images.githubusercontent.com github-production-user-asset-6210df.s3.amazonaws.com gist.github.com; script-src github.githubassets.com; style-src 'unsafe-inline' github.githubassets.com; upgrade-insecure-requests; worker-src github.githubassets.com github.com/assets-cdn/worker/ github.com/assets/ gist.github.com/assets-cdn/worker/
server: github.com
set-cookie: _gh_sess=91gUk2Cb%2BLifBjIPZE8ZPX%2BPkLMQkT7d4X8YRi9Us8js4Corgs3u%2B02jE3SDby%2F7p23ZcDqntaTmfB%2BQeIjzS0S1CuAd9hGr8Lzc86XXCljabzZ%2B9FVthZrcNC7U7eynie0Gsr36F1bE4E%2B6EHHNYeDaU66tti%2Bv%2BWxFpNCgEPTA83qL17ieqfJhihXdw%2BPsCeS5pBbha1vZj12k7AN7Fz8PnH5TL8Hf7O%2FuYgmFtoQvOgtpd%2Fs5cupp5clJkR1GHx75DMvxkMjJBvDwgh5h3w%3D%3D--7y14Qxq5aHvUPGBZ--tvaE5JCHp26czdxkUPjmTA%3D%3D; Path=/; HttpOnly; Secure; SameSite=Lax
set-cookie: _octo=GH1.1.643876837.1753233878; Path=/; Domain=github.com; Expires=Thu, 23 Jul 2026 01:24:38 GMT; Secure; SameSite=Lax
set-cookie: logged_in=no; Path=/; Domain=github.com; Expires=Thu, 23 Jul 2026 01:24:38 GMT; HttpOnly; Secure; SameSite=Lax
x-github-request-id: 9DF2:36131:22BFAE:30F459:688039D6
HTTP/2 200
date: Wed, 23 Jul 2025 01:24:38 GMT
content-type: text/html; charset=utf-8
vary: X-PJAX, X-PJAX-Container, Turbo-Visit, Turbo-Frame, X-Requested-With,Accept-Encoding, Accept, X-Requested-With
etag: W/"0741cddb82d0fee10ee035f498bdbe0a"
cache-control: max-age=0, private, must-revalidate
strict-transport-security: max-age=31536000; includeSubdomains; preload
x-frame-options: deny
x-content-type-options: nosniff
x-xss-protection: 0
referrer-policy: origin-when-cross-origin, strict-origin-when-cross-origin
content-security-policy: default-src 'none'; base-uri 'self'; child-src github.githubassets.com github.com/assets-cdn/worker/ github.com/assets/ gist.github.com/assets-cdn/worker/; connect-src 'self' uploads.github.com www.githubstatus.com collector.github.com raw.githubusercontent.com api.github.com github-cloud.s3.amazonaws.com github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com github-production-user-asset-6210df.s3.amazonaws.com *.rel.tunnels.api.visualstudio.com wss://*.rel.tunnels.api.visualstudio.com objects-origin.githubusercontent.com copilot-proxy.githubusercontent.com proxy.individual.githubcopilot.com proxy.business.githubcopilot.com proxy.enterprise.githubcopilot.com *.actions.githubusercontent.com wss://*.actions.githubusercontent.com productionresultssa0.blob.core.windows.net/ productionresultssa1.blob.core.windows.net/ productionresultssa2.blob.core.windows.net/ productionresultssa3.blob.core.windows.net/ productionresultssa4.blob.core.windows.net/ productionresultssa5.blob.core.windows.net/ productionresultssa6.blob.core.windows.net/ productionresultssa7.blob.core.windows.net/ productionresultssa8.blob.core.windows.net/ productionresultssa9.blob.core.windows.net/ productionresultssa10.blob.core.windows.net/ productionresultssa11.blob.core.windows.net/ productionresultssa12.blob.core.windows.net/ productionresultssa13.blob.core.windows.net/ productionresultssa14.blob.core.windows.net/ productionresultssa15.blob.core.windows.net/ productionresultssa16.blob.core.windows.net/ productionresultssa17.blob.core.windows.net/ productionresultssa18.blob.core.windows.net/ productionresultssa19.blob.core.windows.net/ github-production-repository-image-32fea6.s3.amazonaws.com github-production-release-asset-2e65be.s3.amazonaws.com insights.github.com wss://alive.github.com api.githubcopilot.com api.individual.githubcopilot.com api.business.githubcopilot.com api.enterprise.githubcopilot.com; font-src github.githubassets.com; form-action 'self' github.com gist.github.com copilot-workspace.githubnext.com objects-origin.githubusercontent.com; frame-ancestors 'none'; frame-src viewscreen.githubusercontent.com notebooks.githubusercontent.com; img-src 'self' data: blob: github.githubassets.com media.githubusercontent.com camo.githubusercontent.com identicons.github.com avatars.githubusercontent.com private-avatars.githubusercontent.com github-cloud.s3.amazonaws.com objects.githubusercontent.com release-assets.githubusercontent.com secured-user-images.githubusercontent.com/ user-images.githubusercontent.com/ private-user-images.githubusercontent.com opengraph.githubassets.com copilotprodattachments.blob.core.windows.net/github-production-copilot-attachments/ github-production-user-asset-6210df.s3.amazonaws.com customer-stories-feed.github.com spotlights-feed.github.com objects-origin.githubusercontent.com *.githubusercontent.com; manifest-src 'self'; media-src github.com user-images.githubusercontent.com/ secured-user-images.githubusercontent.com/ private-user-images.githubusercontent.com github-production-user-asset-6210df.s3.amazonaws.com gist.github.com; script-src github.githubassets.com; style-src 'unsafe-inline' github.githubassets.com; upgrade-insecure-requests; worker-src github.githubassets.com github.com/assets-cdn/worker/ github.com/assets/ gist.github.com/assets-cdn/worker/
server: github.com
content-encoding: gzip
accept-ranges: bytes
x-github-request-id: 9DF2:36131:22BFBA:30F46E:688039D6
Convert XPath to CSS selector · GitHub
Show Gist options
Save HughxDev/3320053 to your computer and use it in GitHub Desktop.
{{ message }}
Instantly share code, notes, and snippets.
-
Star
1
(1)
You must be signed in to star a gist -
Fork
1
(1)
You must be signed in to fork a gist
-
Save HughxDev/3320053 to your computer and use it in GitHub Desktop.
Convert XPath to CSS selector
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
// JavaScript function for converting simple XPath to CSS selector. | |
// Ported by Dither from [cssify](https://github.com/santiycr/cssify) | |
// Example: `cssify('//div[@id="girl"][2]/span[@class="body"]//a[contains(@class, "sexy")]//img[1]')` | |
var sub_regexes = { | |
"tag": "([a-zA-Z][a-zA-Z0-9]{0,10}|\\*)", | |
"attribute": "[.a-zA-Z_:][-\\w:.]*(\\(\\))?)", | |
"value": "\\s*[\\w/:][-/\\w\\s,:;.]*" | |
}; | |
var validation_re = | |
"(?P<node>"+ | |
"("+ | |
"^id\\([\"\\']?(?P<idvalue>%(value)s)[\"\\']?\\)"+// special case! `id(idValue)` | |
"|"+ | |
"(?P<nav>//?(?:following-sibling::)?)(?P<tag>%(tag)s)" + // `//div` | |
"(\\[("+ | |
"(?P<matched>(?P<mattr>@?%(attribute)s=[\"\\'](?P<mvalue>%(value)s))[\"\\']"+ // `[@id="well"]` supported and `[text()="yes"]` is not | |
"|"+ | |
"(?P<contained>contains\\((?P<cattr>@?%(attribute)s,\\s*[\"\\'](?P<cvalue>%(value)s)[\"\\']\\))"+// `[contains(@id, "bleh")]` supported and `[contains(text(), "some")]` is not | |
")\\])?"+ | |
"(\\[\\s*(?P<nth>\\d|last\\(\\s*\\))\\s*\\])?"+ | |
")"+ | |
")"; | |
for(var prop in sub_regexes) | |
validation_re = validation_re.replace(new RegExp('%\\(' + prop + '\\)s', 'gi'), sub_regexes[prop]); | |
validation_re = validation_re.replace(/\?P<node>|\?P<idvalue>|\?P<nav>|\?P<tag>|\?P<matched>|\?P<mattr>|\?P<mvalue>|\?P<contained>|\?P<cattr>|\?P<cvalue>|\?P<nth>/gi, ''); | |
function XPathException(message) { | |
this.message = message; | |
this.name = "[XPathException]"; | |
} | |
// Fix for Google Chrome: https://stackoverflow.com/a/5475795/214325 | |
var log = window.console.log.bind(console); | |
function cssify(xpath) { | |
var prog, match, result, nav, tag, attr, nth, nodes, css, node_css = '', csses = [], xindex = 0, position = 0; | |
// preparse xpath: | |
// `contains(concat(" ", @class, " "), " classname ")` => `@class=classname` => `.classname` | |
xpath = xpath.replace(/contains\s*\(\s*concat\(["']\s+["']\s*,\s*@class\s*,\s*["']\s+["']\)\s*,\s*["']\s+([a-zA-Z0-9-_]+)\s+["']\)/gi, '@class="$1"'); | |
if (typeof xpath == 'undefined' || ( | |
xpath.replace(/[\s-_=]/g,'') === '' || | |
xpath.length !== xpath.replace(/[-_\w:.]+\(\)\s*=|=\s*[-_\w:.]+\(\)|\sor\s|\sand\s|\[(?:[^\/\]]+[\/\[]\/?.+)+\]|starts-with\(|\[.*last\(\)\s*[-\+<>=].+\]|number\(\)|not\(|count\(|text\(|first\(|normalize-space|[^\/]following-sibling|concat\(|descendant::|parent::|self::|child::|/gi,'').length)) { | |
//`number()=` etc or `=normalize-space()` etc, also `a or b` or `a and b` (to fix?) or other unsupported keywords | |
throw new XPathException('Invalid or unsupported XPath: ' + xpath); | |
} | |
var xpatharr = xpath.split('|'); | |
while(xpatharr[xindex]) { | |
prog = new RegExp(validation_re,'gi'); | |
css = []; | |
log('working with xpath: ' + xpatharr[xindex]); | |
while(nodes = prog.exec(xpatharr[xindex])) { | |
if(!nodes && position === 0) { | |
throw new XPathException('Invalid or unsupported XPath: ' + xpath); | |
} | |
log('node found: ' + JSON.stringify(nodes)); | |
match = { | |
node: nodes[5], | |
idvalue: nodes[12] || nodes[3], | |
nav: nodes[4], | |
tag: nodes[5], | |
matched: nodes[7], | |
mattr: nodes[10] || nodes[14], | |
mvalue: nodes[12] || nodes[16], | |
contained: nodes[13], | |
cattr: nodes[14], | |
cvalue: nodes[16], | |
nth: nodes[18] | |
}; | |
log('broke node down to: ' + JSON.stringify(match)); | |
if(position != 0 && match['nav']) { | |
if (~match['nav'].indexOf('following-sibling::')) nav = ' + '; | |
else nav = (match['nav'] == '//') ? ' ' : ' > '; | |
} else { | |
nav = ''; | |
} | |
tag = (match['tag'] === '*') ? '' : (match['tag'] || ''); | |
if(match['contained']) { | |
if(match['cattr'].indexOf('@') === 0) { | |
attr = '[' + match['cattr'].replace(/^@/, '') + '*=' + match['cvalue'] + ']'; | |
} else { //if(match['cattr'] === 'text()') | |
throw new XPathException('Invalid or unsupported XPath attribute: ' + match['cattr']); | |
} | |
} else if(match['matched']) { | |
switch (match['mattr']){ | |
case '@id': | |
attr = '#' + match['mvalue'].replace(/^\s+|\s+$/,'').replace(/\s/g, '#'); | |
break; | |
case '@class': | |
attr = '.' + match['mvalue'].replace(/^\s+|\s+$/,'').replace(/\s/g, '.'); | |
break; | |
case 'text()': | |
case '.': | |
throw new XPathException('Invalid or unsupported XPath attribute: ' + match['mattr']); | |
default: | |
if (match['mattr'].indexOf('@') !== 0) { | |
throw new XPathException('Invalid or unsupported XPath attribute: ' + match['mattr']); | |
} | |
if(match['mvalue'].indexOf(' ') !== -1) { | |
match['mvalue'] = '\"' + match['mvalue'].replace(/^\s+|\s+$/,'') + '\"'; | |
} | |
attr = '[' + match['mattr'].replace('@', '') + '=' + match['mvalue'] + ']'; | |
break; | |
} | |
} else if(match['idvalue']) | |
attr = '#' + match['idvalue'].replace(/\s/, '#'); | |
else | |
attr = ''; | |
if(match['nth']) { | |
if (match['nth'].indexOf('last') === -1){ | |
if (isNaN(parseInt(match['nth'], 10))) { | |
throw new XPathException('Invalid or unsupported XPath attribute: ' + match['nth']); | |
} | |
nth = parseInt(match['nth'], 10) !== 1 ? ':nth-of-type(' + match['nth'] + ')' : ':first-of-type'; | |
} else { | |
nth = ':last-of-type'; | |
} | |
} else { | |
nth = ''; | |
} | |
node_css = nav + tag + attr + nth; | |
log('final node css: ' + node_css); | |
css.push(node_css); | |
position++; | |
} //while(nodes | |
result = css.join(''); | |
if (result === '') { | |
throw new XPathException('Invalid or unsupported XPath: ' + match['node']); | |
} | |
csses.push(result); | |
xindex++; | |
} //while(xpatharr | |
return csses.join(', '); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You can’t perform that action at this time.