xpath: manipulación de cadenas

Así que en mi proyecto descarado pude aislar algunos campos en particular, uno de los campos devuelve algo como:

[Rank Info] on 2013-06-27 14:26 Read 174 Times 

el cual fue seleccionado por expresión:

 (//td[@class="show_content"]/text())[4] 

Por lo general, hago un procesamiento posterior para extraer la información de fecha y hora, es decir, 2013-06-27 14:26 Ahora que he aprendido un poco más sobre la manipulación de la subcadena xpath, me pregunto si es posible extraer esa parte de información en primer lugar, es decir, en la propia expresión xpath?

Gracias,

Scrapy usa XPath 1.0, que tiene capacidades de manipulación de cadenas muy limitadas, especialmente no admite expresiones regulares. Hay dos formas de cortar una cadena, demuestro ambas con un ejemplo para reducir a la subcadena que estás buscando.

Por índice de caracteres

Esto está bien si los índices de caracteres no cambian (pero el contenido podría).

 substring($string, $start, $len) substring(//td[@class="show_content"]/text(), 16, 16) 

Por pre / sufijo Búsqueda

Esto está bien si el índice puede cambiar, pero los contenidos inmediatamente antes y después de la cadena siguen siendo los mismos:

 substring-before($string, $needle) substring-after($string, $needle) substring-before( substring-after(//td[@class="show_content"]/text(), 'on '), ' Read') 

En todas las otras respuestas hasta el momento, no solo no es útil el /text() , sino que es potencialmente (o incluso probable) un problema. Para los lectores del archivo, deben ser conscientes de los problemas con /text() en las direcciones para los argumentos de una función. En mi trabajo profesional, hay muy (muy pocos) requisitos para tratar el text() directamente.

Estoy hablando de estas expresiones de los otros mensajes:

 substring-after(//td[@class='show_content']/text(), 'on ') 

y

 substring(//td[@class='show_content']/text(), 16, 10) 

Dejemos de lado el problema de que “//” se usa cuando no se debe usar. En XSLT 1.0 solo se consideraría el primer

y en XSLT 2.0 se desencadenaría un error de tiempo de ejecución por más de un singleton para el primer argumento.

Considere este XML modificado si fuera la entrada:

  [Rank Info] on 2013-06-27 14:26 Read 174 Times 

… donde “on” está en el segundo nodo de texto (el primer nodo de texto tiene “[“). En XSLT 1.0, ambas expresiones devuelven la cadena vacía. En XSLT 2.0, ambas expresiones activan errores en tiempo de ejecución.

Considere este XML modificado si fuera la entrada:

  [Rank Info] on 2013-06-27 14:26 Read 174 Times 

En ambos casos, los elementos secundarios text text() de

no incluyen la cadena “on” porque es un nodo de texto descendente, no un nodo de texto secundario.

En ambas expresiones, entonces, lo siguiente funcionaría para ambas entradas modificadas porque una de ellas trata con el valor del elemento, no con el valor de los nodos de texto. El valor del elemento es la concatenación de todos los nodos de texto descendientes.

Asi que:

 substring-after(td[@class='show_content'], 'on ') 

y

 substring(td[@class='show_content'], 16, 10) 

Actuaría sobre el valor completo de la cadena que se encuentra en el elemento. Pero incluso lo anterior tendrá problemas de cardinalidad si hay más de un hijo

por lo que la expresión tendrá que volver a escribirse de todos modos.

Lo que quiero decir es que el uso de text() me llamó la atención y les digo a mis alumnos que si piensan que necesitan usar text() en una expresión XPath, tienen que volver a pensar porque en la mayoría de los casos no lo hacen.

Esto debería funcionar

 substring(//td[@class="show_content"]/text(), 16, 10) 

Pero estoy de acuerdo con Blender, el postprocesamiento en código es mejor para este propósito.