<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 閱讀(4871) 評論(0)  編輯  收藏 所屬分類: Clojure
        XML處理也是個常見的編程工作,雖然說在Clojure里你很少使用XML做配置文件,但是跟遺留系統集成或者處理和其他系統通訊,可能都需要處理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"]}]}]}

    這是一個嵌套的數據結構,每個節點都是clojure.xml/element結構,element包括:
    (defstruct element :tag :attrs :content)
       tag、attrs和content屬性,tag就是該節點的標簽,attrs是一個屬性的map,而content是它的內容或者子節點。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節點是root node,它的content就是三個book子節點,子節點組織成一個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做解析的。同樣它還有個方法,可以將解析出來的結構還原成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>

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

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

        更進一步,如果你想操作parse解析出來的這棵樹,你還可以利用clojure.zip這個標準庫,它有xml-zip函數將xml轉換成zipper結構,并提供一系列方法來操作這棵樹:
    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,來查找節點的鄰近節點,可以通過node來得到節點本身。一切顯得那么自然。更進一步,你還可以“編輯“這棵樹,比如刪除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更改節點等。因此編輯XML并重新生成,你一般可以利用clojure.zip來更改樹,最后利用clojure.xml/emit將更改還原為xml。

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

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

        轉載請注明出處:http://www.tkk7.com/killme2008/archive/2012/02/18/370233.html   
    主站蜘蛛池模板: 亚洲AV无码一区二区三区人| 亚洲综合熟女久久久30p| 亚洲a一级免费视频| 成人无码精品1区2区3区免费看| 亚洲国产香蕉人人爽成AV片久久 | 最近2019免费中文字幕视频三| 亚洲AV无码国产精品色午友在线 | 亚洲av无码电影网| 久久久高清免费视频| 亚洲一区二区三区免费观看| 免费精品国偷自产在线在线 | 日本亚洲欧洲免费天堂午夜看片女人员| 国产黄在线播放免费观看| 亚洲男人av香蕉爽爽爽爽| 特级做A爰片毛片免费看无码| 亚洲精品自在在线观看| 色欲A∨无码蜜臀AV免费播| 亚洲免费在线播放| 午夜宅男在线永久免费观看网| 亚洲天堂免费在线| 四虎免费永久在线播放| 一区二区三区免费看| 亚洲av日韩av无码黑人| 日韩版码免费福利视频| 337p日本欧洲亚洲大胆人人| 国内精品99亚洲免费高清| 无码日韩精品一区二区免费暖暖| 亚洲午夜久久久精品电影院| 国产精品视_精品国产免费 | 免费一区二区三区| 91情国产l精品国产亚洲区| 免费人成在线视频| 人人鲁免费播放视频人人香蕉| 久久久影院亚洲精品| 九九九精品成人免费视频| 一级做α爱过程免费视频| 337p日本欧洲亚洲大胆精品555588| 成人片黄网站A毛片免费| 岛国精品一区免费视频在线观看| 中文字幕在线观看亚洲| 凹凸精品视频分类国产品免费|