<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   
    主站蜘蛛池模板: 欧美男同gv免费网站观看| 国产成人无码免费视频97| 亚洲欧美一区二区三区日产| 又粗又硬免费毛片| 久久美女网站免费| 亚洲国产成人AV在线播放| 亚洲精品高清国产一线久久| 在线观看无码AV网站永久免费| 国产A∨免费精品视频| 国产成人精品亚洲日本在线| 亚洲偷自拍拍综合网| 无遮免费网站在线入口| 国产国产人免费人成成免视频| 亚洲午夜国产精品无卡| 亚洲人成网77777亚洲色| 最近中文字幕无吗免费高清| 免费国产污网站在线观看| 中文字幕精品三区无码亚洲| 国产亚洲一区二区在线观看| 日韩一品在线播放视频一品免费| 日韩免费在线视频| 黄网站色成年片大免费高清| 亚洲国产成人久久77| 亚洲人成人无码网www电影首页| 午夜dj在线观看免费视频| 99久久人妻精品免费二区| 九九九精品视频免费| 亚洲欧美日韩综合久久久久| 久久精品国产亚洲av高清漫画| 亚洲乱码日产精品a级毛片久久| 国产一精品一AV一免费孕妇| 免费视频精品一区二区三区| 午夜成人无码福利免费视频| 亚洲色丰满少妇高潮18p| 亚洲精品国产免费| 久久亚洲精品国产精品黑人| 亚洲线精品一区二区三区影音先锋| 国产成人免费全部网站| 成年女人毛片免费视频| 麻豆高清免费国产一区| 最近2019中文免费字幕在线观看 |