Chapter 28《Working with XML》

半結(jié)構(gòu)化數(shù)據(jù)

  • XML是一種半結(jié)構(gòu)化數(shù)據(jù),既不是純文本數(shù)據(jù)也不是編程中使用到的數(shù)據(jù)結(jié)構(gòu)赁严。在保存數(shù)據(jù)到文件中或?qū)ξ募M行網(wǎng)絡傳輸?shù)臅r候非常有用,將數(shù)據(jù)轉(zhuǎn)換為半結(jié)構(gòu)數(shù)據(jù)员帮,然后使用庫中的工具將半結(jié)構(gòu)數(shù)據(jù)轉(zhuǎn)換為二進制數(shù)據(jù)榜轿。

XML簡介

  • XML的組成元素為TagText幽歼,Tag之間是不能交叉的,可以嵌套谬盐。Tag可以有自己的屬性甸私,屬性就是一個name-value對,nameplain的飞傀,value值被“”或者‘’包裹起來皇型。

XML字面量

  • Scala支持XML字面量砸烦,XML字面量是一個表達式弃鸦,可用在任意表達式可使用的地方,類型是Scala.xml.Elem幢痘,是一個XML元素唬格,其余的重要的類有:Node,是XML所有節(jié)點類的抽象總類颜说;Text购岗,只包含有文本的Node
  • NodeSeq類含有Node序列门粪,許多XML的庫都支持對NodeSeq的操作喊积,Node繼承自NodeSeq
    構(gòu)造XML字面量的時候可以在其中嵌入Scala表達式玄妈,使用{}包括起來注服。如果在表達式中插入Tag,直接寫入即可措近。直接寫入<old></old>標簽溶弟,空節(jié)點使用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>
    

其中<,>$會被轉(zhuǎn)義成為對應的字符實體瞭郑。如果使用單純的字符串拼接辜御,則無法阻止用戶對XML的修改,會造成錯誤的情況發(fā)生屈张。

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

所以最好還是使用XML字面量來生成XML Elem擒权。

序列化

  • 第一種序列化:在內(nèi)部的數(shù)據(jù)結(jié)構(gòu)中定義一個toXML方法,使用XML字面量手動構(gòu)建XML阁谆。

拆分XML

  • 方法基于XPath語言碳抄,可以直接在Scala中使用。使用text方法可以直接提取到XML節(jié)點之間的文字场绿,其中的<,>$可以被自動的轉(zhuǎn)換剖效。
    使用\可以提取XML中的子節(jié)點。
    使用\\可以提取任意深度的子節(jié)點。
    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,將其反序列化為相應的數(shù)據(jù)結(jié)構(gòu)爷光。

加載和保存

  • 序列化的最后一步是XML和字節(jié)之間的轉(zhuǎn)換垫竞,這部分一般都有相應的庫函數(shù)來做。將XML轉(zhuǎn)為String蛀序,調(diào)用toString即可欢瞪,但還是推薦使用scala.xml.XML.save("therm1.xml", node)函數(shù)將XML轉(zhuǎn)為文件進行保存,同時可以指定文件的編碼徐裸。導入更簡單引有,使用 val loadnode = xml.XML.loadFile("therm1.xml")

XML中的模式匹配

  • 以上的例子都是在非常確定XML結(jié)構(gòu)的情況下做的序列化和反序列化,如果一個XML的結(jié)構(gòu)是不確定的倦逐,則使用模式匹配來篩選可能性。用于匹配的模式非常像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只能匹配只有一個節(jié)點的XML健民,例如<a>apple</a><b><c/></b>此類可以贫贝,標簽中間只能有一個節(jié)點秉犹,不能有多的節(jié)點。<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中,換行或者空格等空白字符也都是一個節(jié)點也搓,

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末赏廓,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子傍妒,更是在濱河造成了極大的恐慌幔摸,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件颤练,死亡現(xiàn)場離奇詭異既忆,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門尿贫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來电媳,“玉大人,你說我怎么就攤上這事庆亡∝遗遥” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵又谋,是天一觀的道長拼缝。 經(jīng)常有香客問我,道長彰亥,這世上最難降的妖魔是什么咧七? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮任斋,結(jié)果婚禮上继阻,老公的妹妹穿的比我還像新娘。我一直安慰自己废酷,他們只是感情好瘟檩,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著澈蟆,像睡著了一般墨辛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上趴俘,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天睹簇,我揣著相機與錄音,去河邊找鬼寥闪。 笑死太惠,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的疲憋。 我是一名探鬼主播垛叨,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼柜某!你這毒婦竟也來了嗽元?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤喂击,失蹤者是張志新(化名)和其女友劉穎剂癌,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體翰绊,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡佩谷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年旁壮,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谐檀。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡抡谐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出桐猬,到底是詐尸還是另有隱情麦撵,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布溃肪,位于F島的核電站免胃,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏惫撰。R本人自食惡果不足惜羔沙,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望厨钻。 院中可真熱鬧扼雏,春花似錦、人聲如沸夯膀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽棍郎。三九已至,卻和暖如春银室,著一層夾襖步出監(jiān)牢的瞬間涂佃,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工蜈敢, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留辜荠,地道東北人。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓抓狭,卻偏偏與公主長得像伯病,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子否过,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容