XML parsing in Scala doesn't seem to be as easy and straightforward as it should be.
What I needed was something that behaved similar to document.getElementsByTagName(name) in JavaScript, but for my purposes all I needed was the first element of a particular tag-name. Here is what I ended up with:
import scala.xml.{Document, Elem, Node}
import scala.xml.parsing.ConstructingParser
def _getFirstMatchingElementByName(search: String, n: Node): Option[Node] = {
if (n.label == search) {
Some(n)
} else {
var i = 0
var result: Option[Node] = None
try {
while (result == None) {
result = _getFirstMatchingElementByName(search, n.child(i))
i += 1
}
} catch {
case e: IndexOutOfBoundsException => None
}
result
}
}
It basically recurses through until a match is found or all possibilities are exhausted.
Now that the feature which required that I have this ability has been released I have reviewed this a little more and it really bugs me. I'm sure there are many Java libraries available to help开发者_如何转开发 parse XML, but given the native support that Scala has for generating XML (i.e. it can pretty much just be inlined anywhere), I am curious if I am missing something.
Is there a better way to do this in Scala?
You doing it wrong!
all I needed was the first element of a particular tag-name
given this xml:
val page =
<root>
<need>text1</need>
<doesnotneed>text2</doesnotneed>
<doesnotneed>text3</doesnotneed>
<need>text4</need>
</root>
Now calling this code will give you list of all nodes with given tag name:
scala> page \\ "need"
res3: scala.xml.NodeSeq = NodeSeq(<need>text1</need>, <need>text4</need>)
To get only first one:
scala> page \\ "need" head
res4: scala.xml.Node = <need>text1</need>
P.S. deep-first element would be treated as head.
精彩评论