本节主要内容

  1. XML 字面量
  2. XML内容提取
  3. XML对象序列化及反序列化
  4. XML文件读取与保存
  5. XML模式匹配

1. XML 字面量

XML是一种很重要的半结构化数据表示方式,眼下大量的应用依赖于XML。这些应用或利用XML作为数据交换格式。或利用XML进行文件配置等。像JAVA、C++及其他流行的程序开发语言都是依赖于第三方库来实现XML的操作,比如JAVA常常通过JDOM,DOM4J等XML处理工具进行XML的操纵,但Scala提供了对XML的原生支持,通过scala.xml._包下的类或对象能够进行不论什么的XML操作。以下的代码演示了Scala中怎样定义XML字面量。

scala> var x: scala.xml.Elem = <site><name>xuetuwuyou</name><url>http://www.xuet
uwuyou.com/</url></site>
x: scala.xml.Elem = <site><name>xuetuwuyou</name><url>http://www.xuetuwuyou.com/
</url></site> scala> <site><name>xuetuwuyou</name><url>http://www.xuetuwuyou.com/</url></site> res8: scala.xml.Elem = <site><name>xuetuwuyou</name><url>http://www.xuetuwuyou.c
om/</url></site>

通过上面的代码不能发现,scala会自己主动地对XML进行解析。并识别为scala.xml.Elem类型。scala中与XML相关的包和类很多。详细例如以下图所看到的:

在深入解说Scala操纵XML之前,先对几个基本的术语进行介绍:



图中描写叙述了属性、根元素、子元素、元素及文本的概念及它们之间的关联关系,所以的文本、元素被统称为节点(Node)。以下给出的scala XML中的几个重要的类:

  • Node类。它的一个抽象类。用于对象XML中的全部节点进行抽象:

  • Text类,仅包括文本的节点,比如<url>http://www.xuetuwuyou.com/</url> 中的http://www.xuetuwuyou.com/就是一种Text对象
  • NodeSeq类,它相同是一个抽象类,指的是节点的序列,Node继承自NodeSeq,能够看Node可作是NodeSeq仅仅有一个元素的情况。

scala中的XML中能够运行scala表达式,比如

 val s="http://www.xuetuwuyou.com/"
val xmlUrl= <a>{" "+s+" "}</a>
//<a> http://www.xuetuwuyou.com/ </a>
println(xmlUrl) val age=30
val xml1= if(age<29) <age> {age} </age> else NodeSeq.Empty
//<age> 28 </age
println(xml1) //<age> 79 </age>
val xml2= <age> {29+50} </age>
println(xml2)

2. XML内容提取

提取XML中的文本:

object ExtractXMLText extends App{
val x= <person><name>摇摆少年梦</name><age>27</age></person>
//摇摆少年梦27
println(x.text)
}

这样的提取方式将XML中全部的文本内容提取出来并拼接在一起,在实际中我们可能须要精确提取,比方我仅仅想提取name元素中的内容,此时能够採用下列方式:

val x= <person><name>摇摆少年梦</name><age>27</age></person>
//提取name子结点,类型XPATH訪问方式
//<name>摇摆少年梦</name>
println(x \ "name")
//提取name中的文本
println((x \ "name").text) scala> x \ "age"
res2: scala.xml.NodeSeq = NodeSeq(<age>27</age>)

x \ “age” 这样的子元素的提取方式,返回的类型是scala.xml.NodeSeq

\的方式仅仅能提取子元素,不能提取子元素的子元素,比如:

  val x= <persons>
<person><name>摇摆少年梦</name><age>27</age></person>
<person><name>张三</name><age>29</age></person>
<person><name>李四</name><age>30</age></person>
</persons>
//返回空NodeSeq
println(x \ "name")
// \\提取二级子元素
//<name>摇摆少年梦</name><name>张三</name><name>李四</name>
println(x \\ "name")

通过\和\能够提取不论什么XML的子元素及其文本内容,但假设XML元素带有属性。那又怎样提取呢?

val x= <persons>
<person
name="摇摆少年梦" age="27" />
<person><name>张三</name><age>29</age></person>
<person><name>李四</name><age>30</age></person>
</persons>
//用@方式提取name属性
//摇摆少年梦
println(x \\ "@name")

3. XML对象序列化及反序列化

以下给出的是对象的XML序列化操作:


class Person(val name:String,val age:Int){
def toXML()={
<person>
<name>{name}</name>
<age>{age}</age>
</person>
}
}
object XMLSerialization extends App{
val p=new Person("摇摆少年梦",27)
println(p.toXML())
}

反序列化操作:

class Person(val name:String,val age:Int){
//序列化操作
def toXML()={
<person>
<name>{name}</name>
<age>{age}</age>
</person>
}
//反序列化操作
def fromXML(xml:scala.xml.Elem):Person={
new Person((xml \ "name").text,(xml \ "age").text.toInt)
}
override def toString()="name="+name+", age="+age
}
object XMLSerialization extends App{
val p=new Person("摇摆少年梦",27)
val xmlPerson=p.toXML()
val p2=p.fromXML(xmlPerson)
println(p2)
}

4. XML文件读取与保存

前一小节,我们的序列化与反序列化操作都在内存中进行的,在通常的情况下都是将序列化后的XML保存在文件其中,在反序列化时再从文件里读取,实现方式例如以下:

class Person(val name:String,val age:Int){
def toXML()={
<person>
<name>{name}</name>
<age>{age}</age>
</person>
} def fromXML(xml:scala.xml.Elem):Person={
new Person((xml \ "name").text,(xml \ "age").text.toInt)
}
override def toString()="name="+name+", age="+age
}
object XMLSerialization extends App{
val p=new Person("摇摆少年梦",27)
val xmlPerson=p.toXML()
//保存到XML文件其中
scala.xml.XML.save("person.xml", xmlPerson, "UTF-8", true, null)
//从文件里载入XML文件
val loadPerson=scala.xml.XML.loadFile("person.xml")
val p2=p.fromXML(loadPerson)
println(p2)
}

以下给出的是save方法的标签

/** Saves a node to a file with given filename using given encoding
* optionally with xmldecl and doctype declaration.
*
* @param filename the filename
* @param node the xml node we want to write
* @param enc encoding to use
* @param xmlDecl if true, write xml declaration
* @param doctype if not null, write doctype declaration
*/
final def save(
filename: String,
node: Node,
enc: String = encoding,
xmlDecl: Boolean = false,
doctype: dtd.DocType = null
): Unit =

5. XML模式匹配

Scala操纵XML另外一个很强大的地方在于,它能够用于模式匹配,从而很灵活、方便地对XML进行处理:

import scala.xml._

object PatternMatchingXML extends App{
def xmlMatching(node:Node)={
node match {
//XML模式匹配语法,利用{}进行匹配
case <persons>{sub_element}</persons>=> println(sub_element)
//其他未匹配的情况
case _ => println("no matching")
} }
//以下这条语句的运行结果:<person><name>摇摆少年梦</name></person>
xmlMatching(<persons><person><name>摇摆少年梦</name></person></persons>)
//以下这条语句的运行结果:
//no matching
xmlMatching(<persons><person><name>摇摆少年梦</name></person><person><name>摇摆少年梦</name></person></persons>)
}

从上述代码能够看到,<persons>{sub_element}</persons> 仅仅能匹配标签<persons></persons> 中仅仅存在单个子元素的情况,假设具有多个子元素。即子元素构成NodeSeq,则不能匹配。须要进行进一步处理,代码例如以下:

object PatternMatchingXML extends App{
def xmlMatching(node:Node)={
node match {
//_*的方式表示能够匹配多个子元素的情况,假设匹配
//则将匹配的内容赋值给sub_element
case <persons>{sub_element @ _*}</persons>=> println(sub_element)
case _ => println("no matching")
} }
//以下这条语句返回的是:ArrayBuffer(<person><name>摇摆少年梦</name></person>)
//数组中的每一个元素都是Node类型
xmlMatching(<persons><person><name>摇摆少年梦</name></person></persons>)
//以下这条语句返回的是:ArrayBuffer(<person><name>摇摆少年梦</name></person>, <person><name>摇摆少年梦</name></person>)
//数组中的每一个元素都是Node类型
xmlMatching(<persons><person><name>摇摆少年梦</name></person><person><name>摇摆少年梦</name></person></persons>)
}

由于返回的是ArrayBuffer,能够通过for循环遍历对XML子元素中的内容进行提取。如:


def xmlMatching2(node:Node)={
node match {
case <persons>{sub_element @ _*}</persons>=>
for(elm <- sub_element) println("getting "+(elm \ "name").text)
case _ => println("no matching")
} }
//返回结果getting 摇摆少年梦
xmlMatching2(<persons><person><name>摇摆少年梦</name></person></persons>)
//返回结果:
//getting 摇摆少年梦
//getting 摇摆少年梦
xmlMatching2(<persons><person><name>摇摆少年梦</name></person><person><name>摇摆少年梦</name></person></persons>)

加入公众微信号。能够了解很多其他最新Spark、Scala相关技术资讯

Scala入门到精通——第二十七节 Scala操纵XML的更多相关文章

  1. Scala入门到精通——第二十四节 高级类型 (三)

    作者:摆摆少年梦 视频地址:http://blog.csdn.net/wsscy2004/article/details/38440247 本节主要内容 Type Specialization Man ...

  2. Scala入门到精通——第二十九节 Scala数据库编程

    本节主要内容 Scala Mavenproject的创建 Scala JDBC方式訪问MySQL Slick简单介绍 Slick数据库编程实战 SQL与Slick相互转换 本课程在多数内容是在官方教程 ...

  3. Scala入门到精通——第二十二节 高级类型 (一)

    作者:摇摆少年梦 视频地址:http://www.xuetuwuyou.com/course/12 本节主要内容 this.type使用 类型投影 结构类型 复合类型 1. this.type使用 c ...

  4. Scala入门到精通

    原文出自于: http://my.csdn.net/lovehuangjiaju 感谢! 也感谢,http://m.blog.csdn.net/article/details?id=52233484 ...

  5. Scala入门(1)Linux下Scala(2.12.1)安装

    Scala入门(1)Linux下Scala(2.12.1)安装 一.文件准备 1.1 文件名称 scala-2.12.1.tgz 1.2 下载地址 http://www.scala-lang.org/ ...

  6. SaltStack 入门到精通第二篇:Salt-master配置文件详解

    SaltStack 入门到精通第二篇:Salt-master配置文件详解     转自(coocla):http://blog.coocla.org/301.html 原本想要重新翻译salt-mas ...

  7. centos samba/squid 配置 samba配置 smbclient mount fstab自动挂载samba curl -xlocalhost:3128 www.qq.com squid配置 3128 DNSPOD 第二十七节课

    centos  samba/squid 配置  samba配置 smbclient  mount fstab自动挂载samba curl -xlocalhost:3128 www.qq.com squ ...

  8. 风炫安全WEB安全学习第二十七节课 XSS的防御措施

    风炫安全WEB安全学习第二十七节课 XSS的防御措施 XSS防御措施 总的原则 控制好输入/输出 过滤:根据业务需求进行过滤,对email,手机号码这样的输入框进行验证. 转义:所有输出到前端的数据都 ...

  9. Scala入门到精通——第十五节 Case Class与模式匹配(二)

    本节主要内容 模式匹配的类型 for控制结构中的模式匹配 option类型模式匹配 1. 模式的类型 1 常量模式 object ConstantPattern{ def main(args: Arr ...

随机推荐

  1. jquery中empty()和remove()的区别

    empty 顾名思义,清空方法,但是与删除又有点不一样,因为它只移除了 指定元素中的所有子节点. remove与empty一样,都是移除元素的方法,但是remove会将元素自身移除,同时也会移除元素内 ...

  2. Spring Boot + Jersey

    Jersey是一个很好的Java REST API库.当你用Jersey实现REST的时候.是很自然的.同一时候Spring Boot是Java世界中还有一个很好的工具.它降低了程序的应用配置(< ...

  3. Android之RecyclerView简单使用(三)

    使用过ListView滴小伙伴都知道.ListView有这样一个属性android:divider,用来设置每一个item之间切割线滴属性.问题来了,那么RecyclerView这个控件有没有这个属性 ...

  4. 在sublime text 3中安装中文支持 分类: C_OHTERS 2015-04-24 22:04 229人阅读 评论(0) 收藏

    1.安装package control 使用control+~打开终端,然后输入以下内容并确定: import  urllib.request,os;pf='Package Control.subli ...

  5. POJ 1088 滑雪 DFS 记忆化搜索

    http://poj.org/problem?id=1088 校运会放假继续来水一发^ ^ 不过又要各种复习,功课拉下了许多 QAQ. 还有呀,就是昨天被一个学姐教育了一番,太感谢了,嘻嘻^ ^ 好了 ...

  6. 14、USB摄像头(V4L2接口)的图片采集

    参考网站http://www.cnblogs.com/surpassal/archive/2012/12/19/zed_webcam_lab1.html 一.一些知识 1.V4L和V4L2. V4L是 ...

  7. 【50.00%】【codeforces 602C】The Two Routes

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  8. 最简单的基于FFmpeg的移动端样例:IOS HelloWorld

    ===================================================== 最简单的基于FFmpeg的移动端样例系列文章列表: 最简单的基于FFmpeg的移动端样例:A ...

  9. ios开发核心动画三:隐式动画与时钟效果

    一:隐式动画 #import "ViewController.h" @interface ViewController () /** <#注释#> */ @proper ...

  10. css3-9 css中的浮动怎么使用

    css3-9 css中的浮动怎么使用 一.总结 一句话总结:用来做一般的行效果,比如说手机左右分布的头部导航栏.浮动的东西放到一个div中去,里面的内容根据需求左浮动或者右浮动,然后记得加上清除浮动. ...