2010-06-16 15 views
13

¿Cuál es la API más simple de usar en scala para realizar las siguientes consultas XPath en un documento?Realizar consultas XPath complicadas en Scala

//s:Annotation[@type='attitude']/s:Content/s:Parameter[@role='type' and not(text())] 

//s:Annotation[s:Content/s:Parameter[@role='id' and not(text())]]/@type 

(s se define como un apodo para un espacio de nombres particular)

La única documentación que puedo encontrar en librerías XML de Scala no tiene información sobre la realización de complicadas consultas XPath reales.

Me gustó JDOM para este propósito (en Java), pero como JDOM no es compatible con los genéricos, me resultará doloroso trabajar con Scala. (Otras bibliotecas XML para Java han tendido a ser aún más doloroso en Java, pero tengo que admitir que no sé el paisaje real también.)

+0

Lo does 's: ...' significa? Supongo que está relacionado con los espacios de nombres, pero no pude encontrarlo en la especificación XPath. –

+0

Sí, es un prefijo de espacio de nombres. Consulte el penúltimo párrafo de la introducción donde dice "En la siguiente gramática, los nombres no terminales QName y NCName se definen en [Nombres XML], y S se define en [XML]". La expresión 's: Annotation' es un QName. –

Respuesta

3

Creo que voy a ir con el proxenetismo XOM. Es una lástima que los autores de XOM decidieran no exponer colecciones de nodos secundarios y similares, pero tenían más trabajo y menos ventajas para hacerlo en Java que en Scala. (Y es una biblioteca bien diseñada)

EDIT: Terminé con el proxenetismo JDOM después de todo, porque XOM no compila consultas XPath con anticipación. Como la mayor parte de mi esfuerzo estuvo dirigido a XPath esta vez, pude encontrar un buen modelo que elude la mayoría de los problemas genéricos. No debería ser demasiado difícil encontrar versiones genéricas razonables de los métodos getChildren y getAttributes y en org.jdom.Element (robando la biblioteca con nuevos métodos que tienen nombres ligeramente modificados). No creo que haya una solución para getContent, y no estoy seguro acerca de getDescendants.

+0

he publicado el código completo de mi envoltorio JDOM en http: // stackoverflow. com/preguntas/4228149/es llevar a cabo-a-XPath-string-consulta usando-scalas-XML-biblioteca-no-a-way-a/4228822 # 4228822 –

12
//s:Annotation[@type='attitude']/s:Content/s:Parameter[@role='type' and not(text())] 

Bueno, no entiendo la notación s:, y couldn Tampoco lo encontrará en la especificación XPath. Sin embargo, haciendo caso omiso de que este sería el siguiente:

(
    (xml 
    \\ "Annotation" 
    filter (_ \ "@type" contains Text("x")) 
) 
    \ "Content" 
    \ "Parameter" 
    filter (el => (el \ "@type" contains Text("type")) && el.isInstanceOf[Text]) 
) 

nota la necesidad de paréntesis debido a la mayor precedencia de \ sobre filter. He cambiado el formato a una expresión de varias líneas ya que el equivalente de Scala es demasiado detallado para una sola línea.

No puedo responder sobre espacios de nombres, sin embargo. No hay idea de cómo trabajar con ellos en las búsquedas, si es posible. Los documentos mencionan @{uri}attribute para atributos prefijados, no menciona nada sobre elementos prefijados. Además, tenga en cuenta que debe pasar un uri que se resuelve en el espacio de nombres que desea, ya que los espacios de nombres literales en la búsqueda no son compatibles.

+0

bueno, eso es feo, pero al menos es factible. –

+4

@Ken Todas las bibliotecas de Java están disponibles ... Creo que es una lástima no tener una mejor compatibilidad con XPath. –

+0

en lugar de: (filtro xml \\ "Anotación" (_ \ "@type" contiene Texto ("x"))) Yo usaría: (filtro xml \\ "Anotación" (x => (x \ "@type"). text == "x")) –

1

Supongo que cuando scalaxmljaxen sea maduro, podremos hacerlo de forma fiable en las clases de XML integradas de scala.

3

Scales Xml añade tanto de cadena evaluación completa XPath con base y un DSL interno que proporciona una cobertura bastante completa para consultar

+0

no se pudo encontrar el "lleno XPath basada cadena" ejemplo , ¿Me estoy perdiendo de algo? –

+0

Consulte http://scala-scales.googlecode.com/svn/sites/scales/scales-xml_2.9.2/0.4.4/StringXPaths.html para obtener un código de ejemplo – Chris

0

se recomienda usar kantan.xpath:

import kantan.xpath._ 
import kantan.xpath.implicits._ 

input.evalXPath[List[String]](xp"/annotation[@type='attitude']/content/parameter[@role='type' and not(text())]/@value") 

Esto produce:

res1: kantan.xpath.XPathResult[List[String]] = Success(List(foobar)) 
Cuestiones relacionadas