Com S 541 Lecture -*- Outline -*- * XML and Scala based on: scala.epfl.ch ** XML construction ------------------------------------------ XML EMBEDDING XML in Scala is: - fragmentary (not whole documents) - represented by instances of scala.xml.Node - immutable ------------------------------------------ Q: So how do you transform XML documents? using functional techniques Technically, the trait Node is a subtype of NodeSeq, (hence Seq) which has some of the interesting methods *** basic literals ------------------------------------------ import scala.xml._; /** Tests of Scala's XML facilities. */ object Hello { def main(args: Array[String]): Unit = { val pp = new PrettyPrinter(80,2); val doc: Node = Hello!

Hello!

; Console.println(XHTML.preamble); Console.println(pp.format(doc)); } } ------------------------------------------ starts with < and then an alphabetic char The PrettyPrinter is just for making human readable output *** Using embedded Scala expressions ------------------------------------------ BACK TO SCALA Including { scala code } in XML: object XHTML { /* ... */ def xhtmlPage(title: String, body: Elem): Node = { title } { body } ; } Nesting: ------------------------------------------ Q: What's the output of the XHTML.xhtmlPage function? Q: How does the list work? *** example ------------------------------------------ package scalaxml; import scala.xml._; import XHTML._; /** Tests of Scala's XML facilities. */ object FlagColors { def main(args: Array[String]): Unit = { val pp = new PrettyPrinter(80,2); val title = "Colors of the United States Flag"; val page: Node = xhtmlPage(title,

{ title }

The colors on the flag of the United States of America, like the colors of many flags from around the world, are as follows.

); Console.println(preamble); Console.println(pp.format(page)); } } ------------------------------------------ ** queries *** Loading XML ------------------------------------------ LOADING XML FROM FILES import scala.xml._; object CopyXML with Application { val pp = new PrettyPrinter(100, 2); val doc = XML.loadFile( "d:/WWW/ComS541/index.shtml"); Console.println(XHTML.preamble); Console.println(pp.format(doc)); } ------------------------------------------ XML is an object in the package scala.xml, with loadFile and load ------------------------------------------ LOADING FROM A URL import scala.xml._; import java.net.URL; object CopyXMLFromURL { def main(args: Array[String]): Unit = { assert (args.length == 1); val pp = new PrettyPrinter(100, 2); val ios: java.io.InputStream = new URL(args(0)).openStream(); val doc = XML.load(ios); Console.println(XHTML.preamble); Console.println(pp.format(doc)); } } ------------------------------------------ This uses various Java features from java.net.URL *** pattern matching (for one match) ------------------------------------------ PATTERN MATCHING NODES tbl match { case { rows @ _* }
=> { rows }{ newRow }
} ------------------------------------------ Q: What does this match? everything inside, binding it to cs. note the use of * Q: Why escape back to XML, why not write { cs newEntry } ? sequencing by concatenation works in XML syntax, but not in Scala hence the escape back to XML and then back to Scala. *** queries ------------------------------------------ QUERIES VIA XPATH-LIKE OPERATORS XPath operators: n \ "str" sequence of elements of n in nodes named "str" val d1 = 1 with inner 2 3 d1 \ "b" --> 1 3 0 \ "b" --> Nil n \\ "str" all descendents "str" including self d1 \\ "b" --> 1 2 3 0 \\ "b" --> 0 ------------------------------------------ ------------------------------------------ CAN USE IN FOR COMPREHENSIONS From "Scala by Example": for (val a <- labAddrBook \\ "entry"; val p <- labPhoneBook \\ "entry"; a \ "name" == p \ "name") yield { a.child } { p \ "phone"} ------------------------------------------ the child method returns all children of a node (as a Seq) so a.child is a sequence of the children of a (i.e., contents of the address) ** other features see Burak Emir's projects page, http://lamp.epfl.ch/~emir/projects/, and in particular his book draft on Scala and XML http://lamp.epfl.ch/~emir/projects/scalaxbook.docbk.html See also the API docs