16.XML处理
16.1
回答:
因为scala.xml.Node 实现了方法 def apply(i: Int): Node,所以支持串接调用。
注意:scala-xml-x.x.x.jar 需要另外导入。
scala> val a =
a: scala.xml.Elem =
scala> a(0)
res2: scala.xml.Node =
scala> a(0)(0)
res3: scala.xml.Node =
scala> a(0)(0)(0)
res4: scala.xml.Node =
scala> a(0)(0)(0)(0)
res5: scala.xml.Node =
16.2如下代码的值是什么?
<ul>
<li>Opening bracket: [</li>
<li>Closing bracket: ]</li>
<li>Opening brace: {</li>
<li>Closing brace: }</li>
</ul>
你如何修复它?
回答:会有编译错误。要在XML字面量中包含左花括号和右花括号,连续写两个即可。
package ex16_02
import scala.xml._
object Main extends App{
/*
Multiple markers at this line:
in XML literal: in XML content, please use '}}' to express '}'
I encountered a '}' where I didn't expect one, maybe this tag isn't closed
I encountered a '}' where I didn't expect one, maybe this tag isn't closed
*/
val a =
- Opening bracket: [
- Closing bracket: ]
- Opening brace: {{
- Closing brace: }}
println(a)
}
/*output:
- Opening bracket: [
- Closing bracket: ]
- Opening brace: {
- Closing brace: }
*/
16.3 比对
为什么它们的行为不同?
回答:内嵌表达式中的字符串并不会被转成Text节点而是Atom[String]节点。这和普通的Text节点还是有区别的——Text是Atom[String]的子类。
这对于保存文档没有问题。但如果你事后打算以Text节点的模式对它做匹配时,匹配会失败。像这种情况你应该插入Text节点而不是字符串。
import scala.xml._
object Main extends App {
val a = Fred match { case { Text(t) } => t }
//val b = { "Fred" } match { case { Text(t) } => t }
val c = { Text("Fred") } match { case { Text(t) } => t }
//println("a=" + a)
println("c=" + c)
}
/*output:
a=Fred
b: Exception in thread "main" scala.MatchError: Fred (of class scala.xml.Elem)
c=Fred
*/
16.4读取一个XHTML文件并打印所有不带alt属性的img元素。
import scala.xml._
object Main extends App {
val root = XML.loadFile("./src/test.xhtml")
val imgs: NodeSeq = root \\ "img"
// img \ "@alt " 's type is scala.xml.NodeSeq
for (img <- imgs if (img \ "@alt").text == "") println(img)
}
/*output:
*/
test.xhtml
My Scala
Hello Scala



16.5打印XHTML文件中所有图像的名称。即,打印所有位�%@A�img元素内的src属性值。
import scala.xml._
object Main extends App {
val root = XML.loadFile("./src/test.xhtml")
val imgs: NodeSeq = root \\ "img"
// img \ "@alt " 's type is scala.xml.NodeSeq
imgs.foreach { x => println(x \ "@src" text) }
}
/*output:
hamster.jpg
frog.jpg
dog.jpg
*/
16.6读取XHTML文件并打印一个包含了文件中给出的所有超链接及其URL的表格。
即,打印所有a元素的child文本和href属性。
import scala.xml._
object Main extends App {
val root = XML.loadFile("./src/oschina.xhtml")
val imgs: NodeSeq = root \\ "a"
imgs.foreach { x =>
val child = x.child
println("%s: %s".format(child(0).text, x.attribute("href").getOrElse("")))
}
}
/*output:
Android: http://www.oschina.net/app
iPhone: http://www.oschina.net/app
WP7: http://www.oschina.net/app
*/
oschina.xml:
My Scala
Hello Scala



16.7编写一个函数,带一个类型为Map[String, String]的参数,返回一个dl元素,其中针对映射中每个键对应有一个dt,每个值对应有一个dd。例如:
Map("A" -> "1", "B" -> "2")
应产出
import scala.xml._
object Main extends App {
def genDl(input: Map[String,String])={
{for((k,v) <- input) yield - {k}
- {v}
}
}
val input = Map("A" -> "1", "B" -> "2")
println(genDl(input))
}
/*output:
- A
- 1
- B
- 2
*/
16.8编写一个函数,接受dl元素,将它转成Map[String,String]。该函数应该是前一个练习中的反向处理,前提是所有dt后代都是唯一(各不相同)的。
import scala.xml._
import scala.collection.mutable.Map
object Main extends App {
def dl2map(input: scala.xml.Elem): Map[String, String] = {
val map = Map[String, String]()
val keys = input \ "dt"
val values = input \ "dd"
for (i <- 0 until keys.size) map += keys(i).text -> values(i).text
map
}
val input = - A
- 1
- B
- 2
val obj = dl2map(input)
println(obj)
}
/*output:
Map(A -> 1, B -> 2)
*/
16.9对一个XHTML文档进行变换,对所有不带alt属性的img元素添加一个alt="TODO"属性,其余内容完全不变。
import scala.xml._
import scala.xml.transform._
object Main extends App {
def transform(filename: String) {
val root = XML.loadFile(filename)
val rule1 = new RewriteRule {
override def transform(n: Node) = n match {
case x @
=> if (x.attributes("alt") == null) x.asInstanceOf[Elem] % Attribute(null, "alt", "TODO", scala.xml.Null) else x
case _ => n
}
}
val transformed = new RuleTransformer(rule1).transform(root)
//println(transformed)
scala.xml.XML.save("./src/test_new.xhtml", transformed(0))
}
transform("./src/test.xhtml")
}
/*output:
My Scala
Hello Scala



*/
16.10编写一个函数,读取XHTML文档,执行前一个练习中的变换,并保存结果。确保保存了DTD及所有CDATA内容。
import scala.xml._
import scala.xml.transform._
import scala.xml.parsing.ConstructingParser
import scala.xml.dtd._
object Main extends App {
def transform(filename: String) {
val parser = ConstructingParser.fromFile(new java.io.File(filename), preserveWS = true)
val doc = parser.document
val root = doc.docElem
val rule1 = new RewriteRule {
override def transform(n: Node) = n match {
case x @
=> if (x.attributes("alt") == null) x.asInstanceOf[Elem] % Attribute(null, "alt", "TODO", scala.xml.Null) else x
case _ => n
}
}
val transformed = new RuleTransformer(rule1).transform(root)
//println(transformed)
scala.xml.XML.save("./src/cdata_new.xhtml", transformed(0),
enc = "UTF-8",
xmlDecl = true,
doctype = DocType("html",
PublicID("-//W3C//DTD XHTML 1.0 Strict//EN",
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"),
Nil))
}
transform("./src/cdata.xhtml")
}
/*output:
My Scala
Hello Scala



*/
原文博客地址:http://blog.csdn.net/u011225629/article/details/47618015