快学Scala习题解答—第十六章 XML处理

16.XML处理

16.1(0) 得到什么?(0)(0)呢?为什么?

回答:(0) 得到一个scala.xml.Node,(0)(0)也是得到scala.xml.Node

因为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 比对

  • Fred
  • match { case
  • {Text(t)}
  • => t } 和

  • {"Fred"}
  • match { case
  • {Text(t)}
  • => t }

    为什么它们的行为不同?

    回答:内嵌表达式中的字符串并不会被转成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

    inu

    ? 

    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

    inu

    ? 

    16.7编写一个函数,带一个类型为Map[String, String]的参数,返回一个dl元素,其中针对映射中每个键对应有一个dt,每个值对应有一个dd。例如:

    Map("A" -> "1", "B" -> "2")

    应产出

    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

    TODO

    TODO

    inu

    */


    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

    TODO

    TODO

    inu

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

    ?

    你可能感兴趣的:(scala学习笔记)