《快学Scala》学习笔记--第16章 XML处理

这是一篇《快学scala》的读书笔记,需要具备Scala语言的基础,欢迎读者与我一起探讨,或者教我新知识呀~

16.1 XML字面量

Scala对xml有内建支持,直接用xml代码就行

    import scala.xml.Elem
    import scala.xml.NodeBuffer
    val doc:Elem = <html><head><title>Fred's</title></head></html>
    val item:NodeBuffer = <li>Fred</li><li>wilma</li>

16.2 XML节点

Node类是所有XML节点类型的祖先,两个最重要的子类是Text和Elem。
用child方法遍历父节点下面的每一个子节点

    val ls:Elem = <a herf="www.baidu.com">the<em>scala</em><em>yoyo</em>language</a>
    for(x <- ls.child)
      println(x)

输出结果:

the
scala
yoyo
language

代码:

    val ls:Elem = <a herf="www.baidu.com">the<em><li>hello</li>scala</em><em>yoyo</em>language</a>
    for(x <- ls.child if !x.child.isEmpty)
      println(x.child)

输出结果:

 ArrayBuffer(<li>hello</li>, scala)
 ArrayBuffer(yoyo)

通过变成的方式构建节点序列,可以使用NodeBuffer,是ArrayBuffer[Node]的子类,可以被隐式转换为NodeSeq,转换之后就不能再继续修改它,因为xml节点序列是不可变的

    import scala.xml.{Node, NodeSeq}
    val items = new NodeBuffer
    items += <li>Fred</li>
    items += <li>Wilma</li>
    val nodes:NodeSeq = items

16.3 元素属性

要处理某个元素的属性键和值,可以使用attributes属性,返回Option类型的节点序列

    val ls:Elem = <a href="www.baidu.com">the<em><li>hello</li>scala</em><em>yoyo</em>language</a>
    val url: scala.Seq[Node] = ls.attributes("href")
    val url1:String= ls.attributes("href").text
    println(url1)

输出结果:www.baidu.com
通过调用 text方法返回String类型结果,也可以通过下面的方法避免没有这个属性返回null的结果,如果没有返回空

   val url2 = ls.attributes.get("alt").getOrElse(Text(""))
    println(url2)

遍历节点的所有属性:

    val elem1 = <p class="nihao" type="wawa"></p>
    for(attr <- elem1.attributes)
      println(attr.key,attr.value.text)
    val map:Map[String,String] = elem1.attributes.asAttrMap
    println(map)

两种方式都可以遍历节点的所有属性,第一种方式的attr类型是MetaData,第二种方式返回的是键值对的map

16.4 内嵌表达式

可以在xml字面量中包含Scala的代码块

    val items = List(2,3,5)
    val elem = <ul>{for(i <- items)yield <li>{i}</li>}</ul>
    println(elem)

16.5 在属性中使用表达式

可以用Scala表达式来计算属性值


    val e = <a id={new Atom[Int](1)}></a>
    println(e.attributes("id").text)
    val description = "TOD"
    val q = <img alt={if(description == "TODO") null else description}>yolo</img>
    println(q.attributes.get("alt").getOrElse(Text("")))

16.8 模式匹配

可以在模式匹配表达式中使用xml字面量

    var nodeLs = List(<img/>)
    nodeLs = <li>yolo</li> :: nodeLs
    nodeLs = <ul>lala<li>yilia</li></ul> :: nodeLs
    nodeLs.foreach(_ match {
      case <img/> => println("img")
      case <li>{v}</li> => println(v)
      case <ul>{_*}</ul> => println("lala")
      case _ => println("")
    })

可以用下面的方式匹配文本

 <li>{Text(v)}</li> => v
 <li>v</li> => v.text

XML模式不能有属性,如果要匹配属性,需要用守卫

    var nodeLs = List(<img/>)
    nodeLs = <li class="name">yolo</li> :: nodeLs
    nodeLs = <ul>lala<li>yilia</li></ul> :: nodeLs
    nodeLs.foreach(_ match {
      case <img/> => println("img")
      case n @ <li>{_}</li> if (n.attributes("class").text == "name")=> println(n)
      case <ul>{_*}</ul> => println("lala")
      case _ => println("")
    })

16.9 修改元素和属性

xml节点和节点序列是不可变的,如果要编辑一个节点,需要创建一个拷贝

    val list = <ul><li>Fred</li><li>Wilma</li></ul>
    val list2 = list.copy(label = "ol")
    println(list2)

结果输出:

  1. Fred
  2. Wilma

新旧两个列表的后代是共享的,要添加一个后代,可以像下面这样调用copy

    val list = <ul><li>Fred</li><li>Wilma</li></ul>
    val list2 = list.copy(label = "ol",child = list.child ++ <li>another</li>)
    println(list2)

更多内容请见我的个人博客:AlisaBen

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值