<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做配置文件,但是跟遺留系統集成或者處理和其他系統通訊,可能都需要處理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无码乱码在线观看代蜜桃 | 亚洲成人免费网址| 成年女人看片免费视频播放器| 国产综合成人亚洲区| 久久久精品国产亚洲成人满18免费网站| 国产色无码精品视频免费| 亚洲国产成人无码av在线播放| 免费国产精品视频| 99re在线视频免费观看| 2019亚洲午夜无码天堂| 国产AⅤ无码专区亚洲AV| 国产在线jyzzjyzz免费麻豆| 日本精品久久久久久久久免费| 亚洲五月激情综合图片区| 精品久久久久久久免费人妻 | 国产亚洲精品免费| 久久大香香蕉国产免费网站| 亚洲熟妇AV日韩熟妇在线| 亚洲精品成人片在线播放| 精品久久久久久久免费人妻| 午夜爽爽爽男女免费观看影院| 亚洲Aⅴ在线无码播放毛片一线天| 亚洲精品乱码久久久久久自慰| 免费特级黄毛片在线成人观看| 成人影片一区免费观看| 亚洲AV无码AV男人的天堂不卡 | 人妻仑乱A级毛片免费看| 亚洲国产精品日韩在线观看| 久久影视综合亚洲| 国外成人免费高清激情视频| 亚洲一区免费观看| 中文字幕免费在线视频| 国产精品亚洲一区二区无码| 亚洲精品成人久久| 亚洲爆乳无码一区二区三区| 免费a级毛片永久免费| 国产精品无码免费播放| 1000部羞羞禁止免费观看视频 | 青娱乐免费在线视频|