I'd like to see a rewrite of bellow script using http://anti-xml.org instead of Scala XML.
This is an excerpt from Chapter 10. Herding XML in Scala - http://ofps.oreilly.com/titles/9780596155957/HerdingXMLInScalaDSLs.html
// code-examples/XML/reading/pattern-matching-script.scala
import scala.xml._
val someXML =
<sammich>
<bread>wheat</bread>
<meat>salami</meat>
<condiments>
<condiment expired="true">mayo</condiment>
<condiment expired="false">mustard</condiment>
</condiments>
</sammich>
someXML match {
case <sammich>{ingredients @ _*}</sammich> => {
for (cond @ <condiments>{_*}</condiments> <- ingredients)
println("condiments: " + cond.text)
}
}
Thanks
I'm not familiar with antixml, however, as there is no other answer, I'll make a try
Just for the record, your code returns
mayo
mustard
More precisely, the string starts with the blanks/newline between the end of and the start of the first . The blanks between mayo and mustard are the ones between the two condiment, and the blanks after mustard is the one before the closing .
In antixml, first thing to do seems to convert your, which is simply
val someAntiXml = someXML.anti
Getting the condiments part is easy :
var condiments = someAntiXml \ 'condiments
Then one has to extract the text. It sounded like the way to do this was
condiments \\ text
But \\
does not traverse the structure in order, it looks like breadth-first traversal. As a consequence, the blanks, which are just under condiments, comes before mayo and mustard, which are one level below, in the elements.
So here is a possible implementation to retrieve the text. Maybe there is a more standard way, but I did not find one.
def textOf(g: Group[Node]) : String =
g.toList.map{
case Elem(_, _, _, _, children) => textOf(children)
case t: Text => t.text
case c: CDATA => c.text
case _ => ""
}.mkString
Then textOf(someAntiXml \ "condiments")
gives the expected result.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With