Cómo comparar cadenas con Xpath 1.0?

Estoy experimentando un problema con el operador < en cadenas en Xpath 1.0.

Esta simple expresión de Xpath

 'A' < 'B' (or the equivalent 'A' < 'B') 

no se evaluó como verdadero en mi ejecución xslt en libxslt (que es un motor XSLT 1.0).

Revisé en XML Spy, que permite probar expresiones de Xpath en 1.0 y 2.0, y efectivamente, en Xpath 2.0 se evalúa como true , pero en Xpath 1.0 se evalúa como false .

¿Es esto un error en Xpath 1.0?

¿Qué otra expresión debería usar para comparar dos cadenas / caracteres para su orden alfabético? Tenga en cuenta que la función compare () no funcionará, ya que es una función XSLT 2.0.

Solutions Collecting From Web of "Cómo comparar cadenas con Xpath 1.0?"

Sí, esto es una limitación de XPath 1.0. (No creo que sea razonable referirse a una limitación que no te gusta como un “error”, aunque es evidente que los diseñadores de XPath 2.0 estuvieron de acuerdo contigo en que era una limitación indeseable).

Ha etiquetado su pregunta “xslt”, por lo que puede solucionar el problema en el nivel XSLT, al menos si su procesador tiene la extensión de conjunto de nodos:

       A comes first!  

Pero tal vez es hora de pasar a 2.0. ¿Qué te detiene?

En XPath 1.0, la comparación de cadenas se define solo para = y != , Y las comparaciones de pedidos no están disponibles. La especificación dice

Cuando ninguno de los objetos a comparar es un conjunto de nodos y el operador es < =, <,> = o>, los objetos se comparan convirtiendo ambos objetos en números y comparando los números de acuerdo con IEEE 754.

Por lo tanto, sus dos operandos se convierten a flotación, convirtiéndolos en NaN.

Creo que el XML de Microsoft agrega funciones de extensión para manejar esto, pero por supuesto esto solo ayuda si estás usando MSXML.

Con la esperanza de que esto también sea útil para otros, a continuación se muestra el código que escribí siguiendo la sugerencia de Michael Kay. Escribí una función de compare personalizada que da los mismos resultados que la de Xpath 2.0. También agregué la etiqueta php a la pregunta para que se encuentre con más frecuencia.

 < ?xml version="1.0" encoding="UTF-8"?>        0         -1 1                

El resultado de ejecutar esto (con entrada ficticia) es

 < ?xml version="1.0"?>  -1 0 1 1  

Para aquellos que deseen probar esto en php por sí mismos, aquí está el código que utilicé:

 < ?php $xslt = new XSLTProcessor(); $xslt->importStylesheet( DOMDocument::load('testCompare.xslt') ); $xslt -> registerPHPFunctions(); $xml = new SimpleXMLElement(''); print $xslt->transformToXML( $xml ); ?> 

Puede ser una solución fea, y no es factible en muchas situaciones, pero para una simple comparación de orden alfabético puede usar translate . El siguiente fragmento es solo un ejemplo que puede ampliarse más:

  translate('A','ABCD','1234') < translate('B','ABCD','1234'); 

Su expresión de traducción debe abarcar todas las letras, mayúsculas y minúsculas, y podría reutilizarse convenientemente definiendo una plantilla con nombre.