Chapter 28《Working with XML》

半结构化数据

  • XML是一种半结构化数据,既不是纯文本数据也不是编程中使用到的数据结构。在保存数据到文件中或对文件进行网络传输的时候非常有用,将数据转换为半结构数据,然后使用库中的工具将半结构数据转换为二进制数据。

XML简介

  • XML的组成元素为TagText,Tag之间是不能交叉的,可以嵌套。Tag可以有自己的属性,属性就是一个name-value对,nameplain的,value值被“”或者‘’包裹起来。

XML字面量

  • Scala支持XML字面量,XML字面量是一个表达式,可用在任意表达式可使用的地方,类型是Scala.xml.Elem,是一个XML元素,其余的重要的类有:Node,是XML所有节点类的抽象总类;Text,只包含有文本的Node,
  • NodeSeq类含有Node序列,许多XML的库都支持对NodeSeq的操作,Node继承自NodeSeq。
    构造XML字面量的时候可以在其中嵌入Scala表达式,使用{}包括起来。如果在表达式中插入Tag,直接写入即可。直接写入<old></old>标签,空节点使用XML.NodeSeq.Empty表达。
    scala> <a> {if (yearMade < 2000) <old>{yearMade}</old> else xml.NodeSeq.Empty} </a>
    
    scala> <a> {"</a>potential security hole<a>"} </a>
    res4: scala.xml.Elem = <a> &lt;/a&gt;potential security
    hole&lt;a&gt; </a>
    

其中<,>$会被转义成为对应的字符实体。如果使用单纯的字符串拼接,则无法阻止用户对XML的修改,会造成错误的情况发生。

scala> "<a>" + "</a>potential security hole<a>" + "</a>"
res5: String = <a></a>potential security hole<a></a>

所以最好还是使用XML字面量来生成XML Elem

序列化

  • 第一种序列化:在内部的数据结构中定义一个toXML方法,使用XML字面量手动构建XML。

拆分XML

  • 方法基于XPath语言,可以直接在Scala中使用。使用text方法可以直接提取到XML节点之间的文字,其中的<,>$可以被自动的转换。
    使用\可以提取XML中的子节点。
    使用\\可以提取任意深度的子节点。
    scala> <a><b><c>hello</c></b></a> \\"c"
    res12: scala.xml.NodeSeq = NodeSeq(<c>hello</c>)
    

同样可以使用这两个方法来提取属性

scala> val joe = <employee name="Joe" rank="code monkey" serial="123"/>
joe: scala.xml.Elem = <employee name="Joe" rank="code monkey" serial="123"/>
scala> joe \\ "@name"
res15: scala.xml.NodeSeq = Joe

"@name",是在被提取的字符串里面的。

反序列化

  • 通过\\可以对一个类定义parser来解析相应的XML,将其反序列化为相应的数据结构。

加载和保存

  • 序列化的最后一步是XML和字节之间的转换,这部分一般都有相应的库函数来做。将XML转为String,调用toString即可,但还是推荐使用scala.xml.XML.save("therm1.xml", node)函数将XML转为文件进行保存,同时可以指定文件的编码。导入更简单,使用 val loadnode = xml.XML.loadFile("therm1.xml")

XML中的模式匹配

  • 以上的例子都是在非常确定XML结构的情况下做的序列化和反序列化,如果一个XML的结构是不确定的,则使用模式匹配来筛选可能性。用于匹配的模式非常像XML字面量,在其中也可以嵌入使用{}包裹的表达式,但{}`中的表达式不再计算,而是一个可以被使用的模式,
    def proc(node: scala.xml.Node): String =
    node match {
    case <a>{contents}</a> => "It's an a: " + contents
    case <b>{contents}</b> => "It's a b: " + contents
    case _ => "It's something else."
    }
    

其中ab只能匹配只有一个节点的XML,例如<a>apple</a>,<b><c/></b>此类可以,标签中间只能有一个节点,不能有多的节点。<a>scala<b/></a>这样是不行的。如果要使提取出来这种XML序列,使用_*进行匹配,可以使用变量绑定,将_*的值赋值到contents上方便以后使用。

def proc(node: scala.xml.Node): String =
node match {
case <a>{contents @ _*}</a> => "It's an a: " + contents
case <b>{contents @ _*}</b> => "It's a b: " + contents
case _ => "It's something else."
}

XML中,换行或者空格等空白字符也都是一个节点,

?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,100评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,308评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,718评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,275评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,376评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,454评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,464评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,248评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,686评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,974评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,150评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,817评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,484评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,140评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,374评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,012评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,041评论 2 351

推荐阅读更多精彩内容