java - Realizar complicadas consultas XPath en Scala
xml jdom (5)
//s:Annotation[@type=''attitude'']/s:Content/s:Parameter[@role=''type'' and not(text())]
Bueno, no entiendo la notación s:
y tampoco pude encontrarla en la especificación XPath. Sin embargo, ignorando que esto se vería así:
(
(xml
// "Annotation"
filter (_ / "@type" contains Text("x"))
)
/ "Content"
/ "Parameter"
filter (el => (el / "@type" contains Text("type")) && el.isInstanceOf[Text])
)
Tenga en cuenta la necesidad de paréntesis debido a una mayor precedencia del filter
/
over. 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.
Sin embargo, no puedo responder sobre los espacios de nombres. No hay idea de cómo trabajar con ellos en las búsquedas, si es posible. Los documentos mencionan el @{uri}attribute
para los @{uri}attribute
prefijados, no menciona nada sobre los 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.
¿Cuál es la API más simple de usar en scala para realizar las siguientes consultas XPath en un documento?
//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 nombre particular)
La única documentación que puedo encontrar en las bibliotecas XML de Scala no tiene información sobre cómo realizar consultas XPath reales complicadas.
A mí me gustaba JDOM (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 dolorosas en Java, pero admito que no conozco el paisaje realmente bien).
Creo que me voy a ir con XOM ligeramente tramposo . 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).
EDITAR: 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 getAdditionalNamespaces
en org.jdom.Element
(mediante el getAttributes
getAdditionalNamespaces
en la biblioteca con nuevos métodos que tienen nombres ligeramente modificados). No creo que haya una getContent
para getContent
, y no estoy seguro de getDescendants
.
Supongo que cuando scalaxmljaxen esté maduro, podremos hacerlo de manera confiable en las clases de XML integradas de Scala.
Scales Xml agrega una evaluación XPath completa basada en cadenas y una DSL interna que proporciona una cobertura bastante completa para consultar
Sugeriría 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))