<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    莊周夢蝶

    生活、程序、未來
       :: 首頁 ::  ::  :: 聚合  :: 管理

    Clojure世界:XML處理

    Posted on 2012-02-18 12:21 dennis 閱讀(4878) 評論(0)  編輯  收藏 所屬分類: Clojure
        XML處理也是個常見的編程工作,雖然說在Clojure里你很少使用XML做配置文件,但是跟遺留系統(tǒng)集成或者處理和其他系統(tǒng)通訊,可能都需要處理XML。

        Clojure的標準庫clojure.xml就是用來干這個事情的。一個簡單的例子如下,首先我們要解析的是下面這個簡單的XML:
    <?xml version="1.0" encoding="UTF-8"?>
    <books>
      
    <book>
        
    <title>The joy of clojure</title>
        
    <author>Michael Fogus / Chris House</author>
      
    </book>
      
    <book>
        
    <title>Programming clojure</title>
        
    <author>Stuart Halloway</author>
      
    </book>
      
    <book>
        
    <title>Practical clojure</title>
        
    <author>Luke Van der Hart</author>
      
    </book>
    </books>

        解析xml用clojure.xml/parse方法即可,該方法返回一個clojure.xml/element這個struct-map組成的一棵樹:
    user=> (use '[clojure.xml])
    nil
    user
    => (parse "test.xml")
    {:tag :books, :attrs nil, :content
     [{:tag :book, :attrs nil, :content [{:tag :title, :attrs nil, :content [
    "The joy of clojure"]} {:tag :author, :attrs nil, :content ["Michael Fogus / Chris House"]}]}
     {:tag :book, :attrs nil, :content [{:tag :title, :attrs nil, :content [
    "Programming clojure"]} {:tag :author, :attrs nil, :content ["Stuart Halloway"]}]}
     {:tag :book, :attrs nil, :content [{:tag :title, :attrs nil, :content [
    "Practical clojure"]} {:tag :author, :attrs nil, :content ["Luke Van der Hart"]}]}]}

    這是一個嵌套的數(shù)據(jù)結(jié)構(gòu),每個節(jié)點都是clojure.xml/element結(jié)構(gòu),element包括:
    (defstruct element :tag :attrs :content)
       tag、attrs和content屬性,tag就是該節(jié)點的標簽,attrs是一個屬性的map,而content是它的內(nèi)容或者子節(jié)點。element是一個struct map,它也定義了三個方法來分別獲取這三個屬性:
    user=> (def x (parse "test.xml"))
    #'user/x
    user=> (tag x)
    :books
    user
    => (attrs x)
    nil
    user
    => (content x)
    [{:tag :book, :attrs nil, :content [{:tag :title, :attrs nil, :content [
    "The joy of clojure"]} {:tag :author, :attrs nil, :content ["Michael Fogus / Chris House"]}]}
    {:tag :book, :attrs nil, :content [{:tag :title, :attrs nil, :content [
    "Programming clojure"]} {:tag :author, :attrs nil, :content ["Stuart Halloway"]}]}
    {:tag :book, :attrs nil, :content [{:tag :title, :attrs nil, :content [
    "Practical clojure"]} {:tag :author, :attrs nil, :content ["Luke Van der Hart"]}]}]
       books節(jié)點是root node,它的content就是三個book子節(jié)點,子節(jié)點組織成一個vector,我們可以隨意操作:
    user=> (tag (first (content x)))
    :book
    user
    => (content (first (content x)))
    [{:tag :title, :attrs nil, :content [
    "The joy of clojure"]} {:tag :author, :attrs nil, :content ["Michael Fogus / Chris House"]}]
    user
    => (content (first (content (first (content x)))))
    [
    "The joy of clojure"]

         額外提下,clojure.xml是利用SAX API做解析的。同樣它還有個方法,可以將解析出來的結(jié)構(gòu)還原成xml,通過emit:
    user=> (emit x)

    <?xml version='1.0' encoding='UTF-8'?>
    <books>
    <book>
    <title>
    The joy of clojure
    </title>
    <author>
    Michael Fogus / Chris House
    </author>
    </book>
    <book>

         如果你要按照深度優(yōu)先的順序遍歷xml,可以利用xml-seq將解析出來的樹構(gòu)成一個按照深度優(yōu)先順序排列節(jié)點的LazySeq,接下來就可以按照seq的方式處理,比如利用for來過濾節(jié)點:
    user=> (for [node (xml-seq x)
                      :when (= :author (:tag node))]
                (first (:content node)))
    ("Michael Fogus / Chris House" "Stuart Halloway" "Luke Van der Hart")

        通過:when指定了條件,要求節(jié)點的tag是author,這樣就可以查找出所有的author節(jié)點的content,是不是很方便?就像寫英語描述一樣。

        更進一步,如果你想操作parse解析出來的這棵樹,你還可以利用clojure.zip這個標準庫,它有xml-zip函數(shù)將xml轉(zhuǎn)換成zipper結(jié)構(gòu),并提供一系列方法來操作這棵樹:
    user=>(def xz (xml-zip x))
    #'user/xz
    user=> (node (down xz))
    {:tag :book, :attrs nil, :content [{:tag :title, :attrs nil, :content [
    "The joy of clojure"]} {:tag :author, :attrs nil, :content ["Michael Fogus / Chris House"]}]}
    user
    => (-> xz down right node)
    {:tag :book, :attrs nil, :content [{:tag :title, :attrs nil, :content [
    "Programming clojure"]} {:tag :author, :attrs nil, :content ["Stuart Halloway"]}]}
    user
    => (-> xz down right right node)
    {:tag :book, :attrs nil, :content [{:tag :title, :attrs nil, :content [
    "Practical clojure"]} {:tag :author, :attrs nil, :content ["Luke Van der Hart"]}]}
    user
    => (-> xz down right right lefts)
    ({:tag :book, :attrs nil, :content [{:tag :title, :attrs nil, :content [
    "The joy of clojure"]} {:tag :author, :attrs nil, :content ["Michael Fogus / Chris House"]}]}
     {:tag :book, :attrs nil, :content [{:tag :title, :attrs nil, :content [
    "Programming clojure"]} {:tag :author, :attrs nil, :content ["Stuart Halloway"]}]})

      是不是酷得一塌糊涂?可以通過up,down,left,right,lefts,rights,來查找節(jié)點的鄰近節(jié)點,可以通過node來得到節(jié)點本身。一切顯得那么自然。更進一步,你還可以“編輯“這棵樹,比如刪除The joy of clojure這本書:
    user=>  (def loc-in-new-tree (remove (down xz)))
    #'user/loc-in-new-tree
    user=> (root loc-in-new-tree)
    {:tag :books, :attrs nil, :content
    [{:tag :book, :attrs nil, :content [{:tag :title, :attrs nil, :content [
    "Programming clojure"]} {:tag :author, :attrs nil, :content ["Stuart Halloway"]}]}
    {:tag :book, :attrs nil, :content [{:tag :title, :attrs nil, :content [
    "Practical clojure"]} {:tag :author, :attrs nil, :content ["Luke Van der Hart"]}]}]}

       ok,只剩下兩本書了,更多方法還包括replace做替換,edit更改節(jié)點等。因此編輯XML并重新生成,你一般可以利用clojure.zip來更改樹,最后利用clojure.xml/emit將更改還原為xml。

        生成xml除了emit方法,還有一個contrib庫,也就是prxml,這個庫的clojure 1.3版本有人維護了一個分支,在這里。主要方法就是prxml,它可以將clojure的數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)換成xml:
    user=>(prxml [:p [:raw! "<i>here & gone</i>"]])
    <p><i>here & gone</i></p>
        顯然,它也可以用于生成HTML。

        xpath的支持可以使用clj-xpath這個開源庫,遺憾的是它目前僅支持clojure 1.2。

        轉(zhuǎn)載請注明出處:http://www.tkk7.com/killme2008/archive/2012/02/18/370233.html   
    主站蜘蛛池模板: 亚洲级αV无码毛片久久精品| 中文字幕在线观看免费| 野花香高清在线观看视频播放免费| 国产片免费福利片永久| 亚洲精品无码久久久久YW| 欧亚精品一区三区免费| 亚洲午夜精品一区二区公牛电影院| 亚洲综合无码一区二区| 香蕉成人免费看片视频app下载| 青草草色A免费观看在线| 亚洲AV中文无码乱人伦| 高潮毛片无遮挡高清免费| 成人亚洲综合天堂| 精品无码一级毛片免费视频观看| 久久亚洲国产成人精品无码区| 本道天堂成在人线av无码免费| 亚洲中文字幕在线第六区| 久别的草原电视剧免费观看| 久久亚洲精品无码AV红樱桃| 国产大片免费网站不卡美女 | 91情侣在线精品国产免费| 亚洲av片不卡无码久久| 男女啪啪永久免费观看网站| 亚洲大尺度无码无码专区| 黄色大片免费网站| 亚洲一本大道无码av天堂| 一区二区三区无码视频免费福利 | 国产国拍亚洲精品mv在线观看| 久久狠狠躁免费观看| 亚洲一级毛片免费看| 国产一级淫片a免费播放口之| 一二三区免费视频| 色www永久免费视频| 产传媒61国产免费| 国产精品麻豆免费版| 久久性生大片免费观看性| 亚洲日本视频在线观看| 国产男女猛烈无遮档免费视频网站| yellow视频免费看| 亚洲a级成人片在线观看| 中文字幕无码精品亚洲资源网|