XPath insensible a mayúsculas y minúsculas contiene () posible?

5 minutos de lectura

XPath insensible a mayusculas y minusculas contiene posible
Aron Woost

Estoy revisando todos los nodos de texto de mi DOM y verifico si el nodeValue contiene una determinada cadena.

/html/body//text()[contains(.,'test')]

Esto es sensible a mayúsculas y minúsculas. Sin embargo, también quiero atrapar Test, TEST o TesT. ¿Es eso posible con XPath (en JavaScript)?

XPath insensible a mayusculas y minusculas contiene posible
Tomalak

Esto es para XPath 1.0. Si su entorno es compatible con XPath 2.0, consulte aquí.


Si. Posible, pero no hermoso.

/html/body//text()[
  contains(
    translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),
    'test'
  )
]

Esto funcionaría para cadenas de búsqueda donde el alfabeto se conoce de antemano. Agregue los caracteres acentuados que espera ver.


Si puedes, marca el texto que te interesa con algún otro medio, como encerrarlo en un <span> que tiene una cierta clase mientras construye el HTML. Esas cosas son mucho más fáciles de localizar con XPath que las subcadenas en el texto del elemento.

Si esa no es una opción, puede dejar que JavaScript (o cualquier otro lenguaje host que esté usando para ejecutar XPath) lo ayude a crear una expresión XPath dinámica:

function xpathPrepare(xpath, searchString) {
  return xpath.replace("$u", searchString.toUpperCase())
              .replace("$l", searchString.toLowerCase())
              .replace("$s", searchString.toLowerCase());
}

xp = xpathPrepare("//text()[contains(translate(., '$u', '$l'), '$s')]", "Test");
// -> "//text()[contains(translate(., 'TEST', 'test'), 'test')]"

(Sugerencia para la respuesta de @KirillPolishchuk: por supuesto, solo necesita traducir los caracteres que realmente está buscando por.)

Este enfoque funcionaría para cualquier cadena de búsqueda, sin necesidad de un conocimiento previo del alfabeto, lo cual es una gran ventaja.

Ambos métodos anteriores fallan cuando las cadenas de búsqueda pueden contener comillas simples, en cuyo caso las cosas se complican más.

  • ¡Gracias! Además, la adición es agradable, traduciendo solo los caracteres necesarios. Me gustaría saber cuál es la ganancia de rendimiento. Tenga en cuenta que xpathPrepare() podría manejar los caracteres que aparecen más de una vez de manera diferente (por ejemplo, obtiene TEEEEEST y teeeeest).

    – Aron Woost

    12 de diciembre de 2011 a las 13:37


  • @AronWoost: Bueno, podría haber alguna ganancia, simplemente compare si está ansioso por averiguarlo. translate() a sí mismo no le importa la frecuencia con la que repites cada carácter – translate(., 'EE', 'ee') es absolutamente equivalente a translate(., 'E', 'e'). PD: No te olvides de votar @KirillPolishchuk, la idea fue suya.

    – Tomalak

    12 de diciembre de 2011 a las 14:19


  • System.Xml.XmlNodeList x = mydoc.SelectNodes(“//*[contains(translate(text(), ‘ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜÉÈÊÀÁÂÒÓÔÙÚÛÇÅÏÕÑŒ’, ‘abcdefghijklmnopqrstuvwxyzäöüéèêàáâòóôùúûçåïõñœ’),’foo’)]”);

    – Stefan Steiger

    29 de noviembre de 2013 a las 9:34

  • No. Ver el “por supuesto, solo necesita traducir los caracteres que realmente está buscando” parte.

    – Tomalak

    29 de noviembre de 2013 a las 10:10

1646059989 244 XPath insensible a mayusculas y minusculas contiene posible
Kirill Polaco

no distingue entre mayúsculas y minúsculas contains

/html/body//text()[contains(translate(., 'EST', 'est'), 'test')]

  • +1 Absolutamente. Eso es algo en lo que no pensé. (Lo usaré en mi respuesta, esto es mucho mejor que la rutina de JavaScript original que escribí)

    – Tomalak

    12 de diciembre de 2011 a las 13:02


  • ¿No se convertiría simplemente TEST para test y vete Test ¿como están las cosas?

    –Muhammad Adeel Zahid

    27 de febrero de 2013 a las 19:10


  • @MuhammadAdeelZahid – No, está reemplazando “T” con “t”, “E” con “e”, etc. Es una coincidencia de 1 a 1.

    – Daniel Halley

    17 abr 2013 a las 19:24

  • Podría ser más claro hacer translate(., 'TES', 'tes'). De esa manera la gente se dará cuenta de que no es una traducción de palabras, es una traducción de letras.

    – mlissner

    1 jun 2017 a las 23:51

  • o ‘EST, ‘est’, aunque se ve genial (aunque un poco críptico) que parte del término buscado aparece en el mapeo (se eliminaron las letras repetidas)

    – Jorge Birbilis

    21 de septiembre de 2020 a las 20:48

1646059989 119 XPath insensible a mayusculas y minusculas contiene posible
kjhughes

Soluciones XPath 2.0

  1. Utilizar minúsculas():

    /html/body//text()[contains(lower-case(.),'test')]

  2. Utilizar partidos() coincidencia de expresiones regulares con su indicador que no distingue entre mayúsculas y minúsculas:

    /html/body//text()[matches(.,'test', 'i')]

  • ¿Esta sintaxis no es compatible con Firefox y Chrome? Acabo de probarlo en la consola y ambos devuelven un error de sintaxis.

    – base de datos

    8 de junio de 2019 a las 11:51

  • Firefox y Chrome solo implementan XPath 1.0.

    – kjhughes

    7 de agosto de 2019 a las 12:17

  • ¿Dónde puedo verificar que esto funcionará como se esperaba?

    – Ankit Gupta

    13 oct 2020 a las 18:04

  • @AnkitGupta: cualquier herramienta en línea o fuera de línea que admita XPath 2.0 se puede usar para verificar esta respuesta, por supuesto, pero (1) las recomendaciones de herramientas están fuera de tema aquí en SO y (2) dados los 56 votos a favor, 0 votos en contra y no comentarios disidentes en más de seis años, puede estar bastante seguro de que esta respuesta es correcta. 😉

    – kjhughes

    13 oct 2020 a las 18:45

Si. Puedes usar translate para convertir el texto que desea hacer coincidir a minúsculas de la siguiente manera:

/html/body//text()[contains(translate(., 
                                      'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
                                      'abcdefghijklmnopqrstuvwxyz'),
                   'test')]

1646059990 591 XPath insensible a mayusculas y minusculas contiene posible
miguel kay

Si está utilizando XPath 2.0, puede especificar una intercalación como el tercer argumento de contains(). Sin embargo, los URI de intercalación no están estandarizados, por lo que los detalles dependen del producto que esté utilizando.

Tenga en cuenta que todas las soluciones dadas anteriormente usando translate() asumen que solo está usando el alfabeto inglés de 26 letras.

ACTUALIZAR: XPath 3.1 define un URI de intercalación estándar para la coincidencia entre mayúsculas y minúsculas.

1646059990 777 XPath insensible a mayusculas y minusculas contiene posible
Endre Ambos

La forma en que siempre hice esto fue usando la función “traducir” en XPath. No diré que es muy bonito, pero funciona correctamente.

/html/body//text()[contains(translate(.,'abcdefghijklmnopqrstuvwxyz',
                                        'ABCDEFGHIJKLMNOPQRSTUVWXYZ'),'TEST')]

espero que esto ayude,

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad