2011-08-14 15 views
13

Algunos nodos en un documento XML tienen espacios de nombres, especificados con un prefijo definido.¿Por qué no hay sintaxis XPath para los nodos calificados de espacio de nombres?

Es posible especificar nombre-local() en XPath 1.0 y omitir los espacios de nombres.

Sin embargo, quiero permitir que el escritor de la XPath encuentre nodos utilizando su nombre completo calificado como identificador.

La forma recomendada es agregar declaraciones de espacio de nombres en el código de invocación (en mi caso, Java). ¡Pero esto significa que la persona que escribe Xpath no tiene la capacidad de trabajar con espacios de nombres!

¿Cómo encontramos los nodos por sus nombres completos utilizando XPath puro?

+2

Si entiendo la pregunta correctamente, usted está preguntando por qué hay una necesidad de declarar un espacio de nombres usando una instrucción como 'addNamespace (" abc "," http://example.com ")' que luego permite hacer una La consulta de Xpath como '/ abc: node', en lugar de usar de alguna manera' http: // example.com' directamente en la consulta. ¿He interpretado la pregunta correctamente? –

+1

@Jong Bor Sí, eso es todo. Sería bueno usar el prefijo abc directamente en la consulta XPath después de declarar que abc = http: //example.com de alguna manera dentro de XPath. Entiendo que las expresiones XPath son cortas y no sería habitual insertar definiciones en ella, pero técnicamente no hay nada que impida que eso sea posible en XPath. –

+1

BTW buena pregunta, +1. Como se supone que los prefijos son simplemente azúcar sintáctico insignificante, mientras que los URI de espacio de nombres son lo que es significativo, se podría pensar que sería útil hacer coincidir un nombre de nodo con el URI de espacio de nombres sin tener que preocuparse por un prefijo, especialmente si XPath proporciona no hay manera de declarar un prefijo. – LarsH

Respuesta

13

No estoy seguro de lo que quiere decir con "como identificador".

¿Cómo encontramos los nodos por sus nombres completamente calificados utilizando XPath puro?

En XPath 1.0, utilizando el nombre local() y namespace-uri(), p.

"*[local-name() = 'foo' and namespace-uri() = 'http://my.org/ns/2.0']" 

En XPath 2.0, hay un conjunto más rico de funciones relacionadas con los espacios de nombres, p. namespace-uri-from-QName(). Pero no estoy seguro de que mejoren lo anterior para lo que quieres.

+1

Bueno, eso tiene sentido. Un poco torpe: prefiero escribir algo como http://my.org/ns/2.0|foo sin estos nombres de funciones, y aún mejor usar prefijos de alguna manera, declararlos en XPath en lugar de en Java, pero esto cumple con el requisito –

+1

Al "usar su nombre completo calificado como espacio de nombres como identificador" Solo quería decir que debería poder hacer referencia a los nodos con precisión, con espacio de nombres + nombre-local. Tu respuesta muestra cómo. –

+0

@JoshuaFox: Estoy de acuerdo, sería muy útil poder declarar prefijos en XPath. Me imagino que hay algunas razones por las que "ellos" decidieron no incluir eso en XPath, pero parece una gran brecha, ya que la solución es muy detallada. – LarsH

1

Usted puede utilizar espacios de nombres durante sus consultas XPath. En Java, lo que necesita proporcionar es una implementación de NamespaceContext si también desea usar prefijos en esas consultas en lugar del espacio de nombres totalmente calificado todo el tiempo. Simplemente agregue una instancia de NamespaceContext a su XPath - Asumiré que utiliza la implementación estándar de JDK, pero el concepto también se aplica a Jaxen u otros.

Luego puede realizar consultas como //customns:Element.

Si no quiere o no puede utilizar un NamespaceContext (por cualquier razón), entonces la única solución parece estar usando los local-name y namespace-uri funciones:

Document doc = ...; 
XPath xp = XPathFactory.newInstance().newXPath(); 
String name = "Element"; 
String ns = "http://www.custom.org/#"; 
String expr = "//*[local-name() = '"+name+" and namespace-uri() = '"+ns+"']"; 
Node node = ((NodeList)xp.evaluate(expr, doc, XPathConstants.NODESET)).item(0); 
+1

Gracias. ¿Qué pasa si estoy dispuesto a usar nombres completos de espacios de nombres y no prefijos? En otras palabras, algo así como. ¿Puedo evitar declarar los espacios de nombres en Java? Mi objetivo es leer en expresiones XPath desde una fuente externa, por lo que prefiero no tener que especificar esto por separado. –

+0

Eso depende de cómo se ve la fuente: si solo tiene una expresión // abc: Elemento y sin declaración de espacio de nombres, entonces, en teoría, está estancado, no hay forma de saber a qué apunta abc. Pero si puede estar absolutamente seguro de que esas expresiones externas tienen los mismos prefijos que su documento de trabajo, entonces aún podría buscar los espacios de nombres correspondientes en su documento y luego construir un NamespaceContext o no usarlo en absoluto. Actualizaré mi respuesta explicando cómo hacerlo. – emboss

+0

Desafortunadamente, parece que no hay [ninguna otra solución] (http://www.jguru.com/forums/view.jsp?EID=1073634) que una combinación de nombre-local() y espacio de nombres-uri(). – emboss

4

XPath 3.0, que actualmente se encuentra en el trabajo el estado del borrador incluirá una expresión literal para URI qualified QNames que permite especificar directamente el espacio de nombres uri.

Éstos son algunos ejemplos de EQNames:

  • pi es un QName léxica sin un prefijo de espacio de nombres.
  • math: pi es un QName léxico con un prefijo de espacio de nombres.
  • "http://www.w3.org/2005/xpath-functions/math":pi especifica el URI de espacio de nombres usando un URILiteral; no es un QName léxico.

creo Saxon 9.3 incluye una aplicación de vista previa de XPath 3.0 que debe ser utilizable a través de la API de Java.

+3

Correcto, aunque las características 3.0 solo pueden habilitarse actualmente en las ediciones comerciales del producto. Preguntas como "por qué esta función no estaba en versiones anteriores" siempre son difíciles de responder, ya sea que nadie las haya propuesto o no hayan presionado lo suficiente o hayan tenido que competir con propuestas rivales para resolver el mismo problema. –

0

La especificación de XPath 3.0 dice:

Q{http://www.w3.org/2005/xpath-functions/math}pi 

Esto funciona en este momento (octubre de 2015), por ejemplo, en eXist-db.

+0

@ e4c5: A XML le gusta usar URI para cosas en su sintaxis literal. Deberías haber leído la respuesta más cuidadosamente. –

+0

@NathanTuggy Sí, tiene razón, mientras que la moderación apareció como una respuesta de solo un enlace (el comentario es insertado automáticamente por el sistema) He eliminado ese comentario. – e4c5

Cuestiones relacionadas