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:
{
for (val c <- List("Red", "White",
"Blue"))
yield - { c }
}
------------------------------------------
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.
{
for (val c <- List("Red", "White",
"Blue"))
yield - { c }
}
);
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
=>
}
------------------------------------------
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