码迷,mamicode.com
首页 > 其他好文 > 详细

快学Scala 第16章 XML处理 习题解答

时间:2015-04-26 13:56:38      阅读:290      评论:0      收藏:0      [点我收藏+]

标签:

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 需要另外导入。

scalaval 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/>

scala> 

 

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 <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>

*/  

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节点而不是字符串。

package ex16_03

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=Fred

b: Exception in thread "main" scala.MatchError: <li>Fred</li> (of class scala.xml.Elem)

c=Fred

*/

4. 读取一个XHTML文件并打印所有不带alt属性的img元素。

package ex16_04

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> 

 

5. 打印XHTML文件中所有图像的名称。即,打印所有位于img元素内的src属性值。

package ex16_05

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

*/


6. 读取XHTML文件并打印一个包含了文件中给出的所有超链接及其URL的表格。

即,打印所有a元素的child文本和href属性。

package ex16_06

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).textx.attribute("href").getOrElse("")))

    }

}

/*output:

Android: http://www.oschina.net/app

iPhone: http://www.oschina.net/app

WP7: 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> 

 

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>

package ex16_07

import scala.xml._

object Main extends App {

 def genDl(inputMap[String,String])={

   <dl>{for((k,v) <- inputyield <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>

*/


8. 编写一个函数,接受dl元素,将它转成Map[String,String]。该函数应该是前一个练习中的反向处理,前提是所有dt后代都是唯一(各不相同)的。

package ex16_08

import scala.xml._

import scala.collection.mutable.Map

object Main extends App {

  def dl2map(input: scala.xml.Elem): Map[StringString] = {

    val map = Map[StringString]()

    val keys = input \ "dt"

    val values = input \ "dd"

    for (i <- 0 until keys.sizemap += 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)

*/

9. 对一个XHTML文档进行变换,对所有不带alt属性的img元素添加一个alt="TODO"属性,其余内容完全不变。

package ex16_09

import scala.xml._

import scala.xml.transform._

object Main extends App {

  def transform(filenameString) {

    val root = XML.loadFile(filename)

    val rule1 = new RewriteRule {

      override def transform(n: Node) = n match {

        case x @ <img/> => if (x.attributes("alt"== nullx.asInstanceOf[Elem] % Attribute(null"alt""TODO", scala.xml.Nullelse 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="TODOsrc="hamster.jpg"/></p>

<p><img alt="TODOsrc="frog.jpg"/></p>

<p><img alt="inusrc="dog.jpg"/></p>

</body>

</html>

*/


10.  编写一个函数,读取XHTML文档,执行前一个练习中的变换,并保存结果。确保保存了DTD及所有CDATA内容。

package ex16_10

import scala.xml._

import scala.xml.transform._

import scala.xml.parsing.ConstructingParser

import scala.xml.dtd._

object Main extends App {

  def transform(filenameString) {

    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"== nullx.asInstanceOf[Elem] % Attribute(null"alt""TODO", scala.xml.Nullelse 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="TODOsrc="hamster.jpg"/></p>

<p><img alt="TODOsrc="frog.jpg"/></p>

<p><img alt="inusrc="dog.jpg"/></p>

</body>

</html>

*/



快学Scala 第16章 XML处理 习题解答

标签:

原文地址:http://my.oschina.net/u/553266/blog/406454

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!