views:

64

answers:

1

I'd like to process a document to retrieve a value that could have more than one path. The ideal signature would look something like:

def value(doc: Elem, potential_paths: List[something]): String

Where it would simply process the doc looking at the head of the potential_paths, if found, return it, otherwise continue with potential_paths.drop(1).

With XPath, the "something" would be a simple list of String's representing XPath statements. Since the "\" is actually a function of the NodeSeq, it's not (apparently) representable separate from a node. Anyway, what's the scala-ish way to approach this?

+4  A: 

Assuming the paths are passed as child/child/child, then you could do this for basic search:

def search(doc: NodeSeq, path: String) =
  path.split('/').foldLeft(doc)(_ \ _)

Processing the whole thing could be done like this:

def value(doc: Elem, potential_paths: List[String]) =
  potential_paths.view.map(search(doc, _)).find(_.nonEmpty)

This assumes Scala 2.8. On Scala 2.7, replace view with projection, and _.nonEmpty with !_.isEmpty.

I used / as a separator here because it's the XPath character and avoids quoting problems. Note that there isn't a leading /, and that <a><b/></a> \ "a" won't find anything, as a isn't a child.

Daniel
folding is pure genius. thanks Daniel...
williamstw