目录
摘要
创建 XML,使用占位符创建 XML,解析 XML,NodeBuffer,保存 XML,序列化与反序列化
Xml
创建 XML
//创建 XML
val langs = <langs>
<lang>Java</lang> <lang>Groovy</lang> <lang>Scala</lang>
</langs>
//格式化输出
val p = new PrettyPrinter(80, 4)
println(p.format(langs))
//输出
/*
<langs>
<lang>Java</lang>
<lang>Groovy</lang>
<lang>Scala</lang>
</langs>
*/
//去除空白
println(scala.xml.Utility.trim(langs))
//<langs><lang>Java</lang><lang>Groovy</lang><lang>Scala</lang></langs>
PrettyPrinter
可以对输出的 XML 增加可读性xml.Utility
可以去除 XML 之间的空白
使用占位符创建 XML
就像普通 String 对象一样可以在 XML 中使用占位符 “{}”
val name = "Bill"
val age = 42
val person = <person>
<name>
{name}
</name> <age>
{age}
</age>
</person>
val p = new PrettyPrinter(80, 4)
println(p.format(person))
//输出
/*
<person>
<name> Bill </name>
<age> 42 </age>
</person>
*/
//list
val fruits = List("apple", "banana", "orange")
val ul = <ul>
{fruits.map(i => <li>
{i}
</li>)}
</ul>
println(p.format(ul))
//输出
/*
<ul>
<li> apple </li>
<li> banana </li>
<li> orange </li>
</ul>
*/
解析 XML
Scala 可以使用 “\” ,”@” 等符号实现基于 XPATH 的访问方式
val weather =
<rss>
<channel>
<title>Yahoo! Weather - Boulder, CO</title>
<item>
<title>Conditions for Boulder, CO at 2:54 pm MST</title>
<forecast day="Thu" date="10 Nov 2011" low="37" high="58" text="Partly Cloudy"
code="29"/>
<forecast day="Fri" date="11 Nov 2011" low="39" high="58"
text="Mostly Cloudy" code="28"/>
<forecast day="Sat" date="12 Nov 2011" low="32" high="49" text="Cloudy"
code="27"/>
</item>
</channel>
</rss>
val forecast = (weather \ "channel" \ "item" \ "forecast")(0)
val day = forecast \ "@day"
val low = (weather \\ "forecast")(0) \ "@low"
println(forecast) //<forecast day="Thu" date="10 Nov 2011" low="37" high="58" text="Partly Cloudy" code="29"/>
println(day, day.getClass) //(Thu,class scala.xml.Group)
println(day.text, day.text.getClass) //(Thu,class java.lang.String)
println(low) //37
val forecastNodes = weather \\ "forecast"
forecastNodes.foreach { n =>
val day = (n \ "@day").text
val date = (n \ "@date").text
val low = (n \ "@low").text
println(s"$day, $date, Low: $low")
}
NodeBuffer
NodeBuffer 继承自 ArrayBuffer。
//nodeBuffer
val x = new xml.NodeBuffer
x += <li>apple</li>
x += <li>banana</li>
val ul2 = <ul>
{x}
</ul>
val p = new PrettyPrinter(80, 4)
println(p.format(ul2))
//outputs
/*
<ul>
<li>apple</li>
<li>banana</li>
</ul>
*/
val nb = new xml.NodeBuffer
val nb2 = nb &+ <li>apple</li> &+ <li>banana</li> &+ <li>cherry</li>
val ul3 = <ul>
{nb2}
</ul>
println(p.format(ul3))
//outputs
/*
<ul>
<li>apple</li>
<li>banana</li>
<li>cherry</li>
</ul>
*/
保存 XML
保存 XML 到本地文件
val portfolio =
<portfolio>
<stocks>
<stock>AAPL</stock>
<stock>AMZN</stock>
<stock>GOOG</stock>
</stocks>
<reits>
<reit>Super REIT 1</reit>
</reits>
</portfolio>
//设置 DocType,可选
val doctype = DocType("html",
PublicID("-//W3C//DTD XHTML 1.0 Strict//EN",
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"),
Nil)
//保存到文件
scala.xml.XML.save("coffeetime-scala/outputs/portfolio.xml", portfolio, "utf-8", true, doctype)
序列化与反序列化
定义需要序列化的 Bean
class Stock(var symbol: String, var businessName: String, var price: Double) {
def toXml = {
<stock>
<symbol>{symbol}</symbol>
<businessName>{businessName}</businessName>
<price>{price}</price>
</stock>
}
override def toString =
s"symbol: $symbol, businessName: $businessName, price: $price"
}
object Stock {
def fromXml(node: scala.xml.Node):Stock = {
val symbol = (node \ "symbol").text
val businessName = (node \ "businessName").text
val price = (node \ "price").text.toDouble
new Stock(symbol, businessName, price)
}
}
//序列化
val aapl = new Stock("AAPL", "Apple", 600d)
println(aapl.toXml)
//outputs
/*
<stock>
<symbol>AAPL</symbol>
<businessName>Apple</businessName>
<price>600.0</price>
</stock>
*/
//反序列化
val googXml = <stock>
<symbol>GOOG</symbol>
<businessName>Google</businessName>
<price>620.00</price>
</stock>
val goog = Stock.fromXml(googXml)
println(goog) //symbol: GOOG, businessName: Google, price: 620.0