快学Scala习题解答—第十六章 XML处理
来源:互联网 发布:网络歌手赚钱吗 编辑:程序博客网 时间:2024/05/17 22:35
16.XML处理
16.1<fred/>(0) 得到什么?<fred/>(0)(0)呢?为什么?
回答:<fred/>(0) 得到一个scala.xml.Node,<fred/>(0)(0)也是得到scala.xml.Node。
因为scala.xml.Node 实现了方法 def apply(i: Int): Node,所以支持串接调用。
注意:scala-xml-x.x.x.jar 需要另外导入。
scala> val a = <fred/>a: scala.xml.Elem = <fred/>scala> a(0)res2: scala.xml.Node = <fred/>scala> a(0)(0)res3: scala.xml.Node = <fred/>scala> a(0)(0)(0)res4: scala.xml.Node = <fred/>scala> a(0)(0)(0)(0)res5: scala.xml.Node = <fred/>
16.2如下代码的值是什么?
<ul>
<li>Opening bracket: [</li>
<li>Closing bracket: ]</li>
<li>Opening brace: {</li>
<li>Closing brace: }</li>
</ul>
你如何修复它?
回答:会有编译错误。要在XML字面量中包含左花括号和右花括号,连续写两个即可。
package ex16_02import 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 <li>I encountered a '}' where I didn't expect one, maybe this tag isn't closed <li> */ val a =<ul> <li>Opening bracket: [</li> <li>Closing bracket: ]</li> <li>Opening brace: {{</li> <li>Closing brace: }}</li> </ul> println(a)}/*output:<ul> <li>Opening bracket: [</li> <li>Closing bracket: ]</li> <li>Opening brace: {</li> <li>Closing brace: }</li> </ul>*/
16.3 比对 <li>Fred</li> match { case <li>{Text(t)}</li> => t } 和
<li>{"Fred"}</li> match { case <li>{Text(t)}</li> => t }
为什么它们的行为不同?
回答:内嵌表达式中的字符串并不会被转成Text节点而是Atom[String]节点。这和普通的Text节点还是有区别的——Text是Atom[String]的子类。
这对于保存文档没有问题。但如果你事后打算以Text节点的模式对它做匹配时,匹配会失败。像这种情况你应该插入Text节点而不是字符串。
import scala.xml._object Main extends App { val a = <li>Fred</li> match { case <li>{ Text(t) }</li> => t } //val b = <li>{ "Fred" }</li> match { case <li>{ Text(t) }</li> => t } val c = <li>{ Text("Fred") }</li> match { case <li>{ Text(t) }</li> => t } //println("a=" + a) println("c=" + c)}/*output:a=Fredb: Exception in thread "main" scala.MatchError: <li>Fred</li> (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:<img src="hamster.jpg"/><img src="frog.jpg"/>*/test.xhtml
<html><head><title>My Scala</title></head><body><p>Hello Scala</p><p><img src="hamster.jpg"/></p><p><img src="frog.jpg"/></p><p><img src="dog.jpg" alt="inu"/></p></body></html>
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.jpgfrog.jpgdog.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/appiPhone: http://www.oschina.net/appWP7: http://www.oschina.net/app*/
oschina.xml:
<html><head><title>My Scala</title></head><body><p>Hello Scala</p><p><img src="hamster.jpg"/></p><p><img src="frog.jpg"/></p><p><img src="dog.jpg" alt="inu"/></p><ul><li><a href="http://www.oschina.net/app" class='android' title='Android客户端'>Android</a></li><li><a href="http://www.oschina.net/app" class='iphone' title='iPhone 客户端'>iPhone</a></li><li><a href="http://www.oschina.net/app" class='wp7' title='Windows Phone 客户端'>WP7</a></li></ul></body></html>
16.7编写一个函数,带一个类型为Map[String, String]的参数,返回一个dl元素,其中针对映射中每个键对应有一个dt,每个值对应有一个dd。例如:
Map("A" -> "1", "B" -> "2")
应产出 <dl><dt>A</dt><dd>1</dd><dt>B</dt><dd>2</dd></dl>
import scala.xml._object Main extends App { def genDl(input: Map[String,String])={ <dl>{for((k,v) <- input) yield <dt>{k}</dt><dd>{v}</dd>}</dl> } val input = Map("A" -> "1", "B" -> "2") println(genDl(input))}/*output:<dl><dt>A</dt><dd>1</dd><dt>B</dt><dd>2</dd></dl>*/
16.8编写一个函数,接受dl元素,将它转成Map[String,String]。该函数应该是前一个练习中的反向处理,前提是所有dt后代都是唯一(各不相同)的。
import scala.xml._import scala.collection.mutable.Mapobject 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 = <dl><dt>A</dt><dd>1</dd><dt>B</dt><dd>2</dd></dl> 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 @ <img/> => 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:<html><head><title>My Scala</title></head><body><p>Hello Scala</p><p><img alt="TODO" src="hamster.jpg"/></p><p><img alt="TODO" src="frog.jpg"/></p><p><img alt="inu" src="dog.jpg"/></p></body></html>*/
16.10编写一个函数,读取XHTML文档,执行前一个练习中的变换,并保存结果。确保保存了DTD及所有CDATA内容。
import scala.xml._import scala.xml.transform._import scala.xml.parsing.ConstructingParserimport 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 @ <img/> => 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:<?xml version='1.0' encoding='UTF-8'?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html><head><title>My Scala</title><script><![CDATA[function matchwo(a,b){if (a < b && a < 0) then { return 1; }else { return 0; }}]]></script></head><body><!-- This is a comment --><p>Hello Scala</p><p><img alt="TODO" src="hamster.jpg"/></p><p><img alt="TODO" src="frog.jpg"/></p><p><img alt="inu" src="dog.jpg"/></p></body></html>*/原文博客地址:http://blog.csdn.net/u011225629/article/details/47618015
- 快学Scala习题解答—第十六章 XML处理
- 快学scala第十六章习题——XML处理
- 《快学Scala》第十六章习题解答
- 《快学Scala》16章习题参考解答(XML)
- 《快学Scala》第二章习题解答
- 《快学Scala》第三章习题解答
- 《快学Scala》第四章习题解答
- 《快学Scala》第五章习题解答
- 《快学Scala》第六章习题解答
- 《快学Scala》第九章习题解答
- 《快学Scala》第十三章习题解答
- 快学Scala习题解答—第五章 类
- 快学Scala习题解答—第六章 对象
- 快学Scala习题解答—第八章 继承
- 快学Scala习题解答—第十章 特质
- 快学Scala习题解答—第十一章 操作符
- 快学Scala习题解答—第十三章 集合
- 快学Scala习题解答—第十一章 操作符
- python监控文件或目录变化-实例,用paramiko远程监控文件夹变化
- md5加密和sha1加密
- 聚集索引和非聚集索引(整理)
- Servlet 中,out.print()与out.write()的区别
- ssh常用用法小结
- 快学Scala习题解答—第十六章 XML处理
- nyoj33 蛇形填数
- Android应用打破65K方法数限制
- linux下安装mysql数据库
- 深入理解PHP之数组(遍历顺序)
- 关于社交小技巧,一篇老文章,与大家分享
- 本博客全文目录索引
- hdu 1712 ACboy needs your help
- 集线,路由和交换的概念