1. /* CSS2XPATH (Still under development)
  2.  * Copyright (c) James Padolsey
  3.  * ---
  4.  * [THIS SCRIPT IS CONTINUALLY UPDATED]
  5.  * LAST UPDATED: 21/03/09
  6.  * CURRENT VERSION: 0.31
  7.  * LOG: http://james.padolsey.com/scripts/javascript/css2xpath_log.txt
  8.  * ---
  9.  * Has been tested on the following selectors:
  10.  * CSS2XPATH('div a'); // => //div//a
  11.  * CSS2XPATH('div#intro a.active'); // => //div[@id='intro']//a[contains(concat(' ',@class,' '),' active ')]
  12.  * CSS2XPATH('#apple pear.lemon'); // => //*[@id='apple']//pear[contains(concat(' ',@class,' '),' lemon ')]
  13.  * CSS2XPATH('ul.nav li:first-child a'); // => //ul[contains(concat(' ',@class,' '),' nav ')]//li[1]//a
  14.  * CSS2XPATH('body > div > p:nth-child(3)'); // => //body/div/p[3]
  15.  * CSS2XPATH('li > input[type="text"]'); // => //li/input[@type="text"]
  16.  */
  17.  
  18. function CSS2XPATH(selector) {
  19. selector = ' ' + selector;
  20. /* The order in which items are replaced is IMPORTANT! */
  21. var regex = [
  22. /* All blocks of 2 or more spaces */
  23. [/\s{2,}/g, function(){
  24. return ' ';
  25. }],
  26. /* additional selectors (comma seperated) */
  27. [/\s*,\s*/g, function(){
  28. return '|//';
  29. }],
  30. /* Attribute selectors */
  31. [/[\s\/]?\[([^\]]+)\]/g, function(m,kv){
  32. return (m.substr(0,1).match(/[\s\/]/) ? '*' : '') + '[@' + kv + ']';
  33. }],
  34. /* :nth-child(n) */
  35. [/:nth-child\((\d+)\)/g, function(m,n){
  36. return '[' + n + ']';
  37. }],
  38. /* :last-child */
  39. [/:last-child/g, function(m,n){
  40. return '[last()]';
  41. }],
  42. /* :first-child */
  43. [/:first-child/g, function(m,n){
  44. return '[1]';
  45. }],
  46. /* "sibling" selectors */
  47. [/\s*\+\s*([^\s]+?)/g, function(m, sib){
  48. return '/following-sibling::' + sib + '[1]';
  49. }],
  50. /* "child" selectors */
  51. [/\s*>\s*/g, function(){
  52. return '/';
  53. }],
  54. /* Remaining Spaces */
  55. [/\s/g, function(){
  56. return '//';
  57. }],
  58. /* #id */
  59. [/([a-z0-9]?)#([a-z][-a-z0-9_]+)/ig, function(m,pre,id){
  60. return pre + (m.match(/^[a-z0-9]/)?'':'*') + '[@id=\'' + id + '\']';
  61. }],
  62. /* .className */
  63. [/([a-z0-9]?)\.([a-z][-a-z0-9]+)/ig, function(m,pre,cls){
  64. return pre + (m.match(/^[a-z0-9]/)?'':'*') + '[contains(concat(\' \',@class,\' \'),\' ' + cls + ' \')]';
  65. }]
  66. ],
  67. len = regex.length;
  68. for (var i = 0; i < len; i++) {
  69. selector = selector.replace(regex[i][0], regex[i][1]);
  70. }
  71. return selector.match(/^\/\//) ? selector : '//' + selector;
  72. }

ALL COPYRIGHT © James Padolsey unless otherwise specified
Go back to the top