2009-07-28 16 views
64

xmlドキュメントとアクセス要素を解析する方法に関する情報が見つかりません。Clojure XMLの解析

私は、XML文書

(clojure.zip/xml-zip (clojure.xml/parse file)) 

(parse-seq file) 

を解析する2つの方法を発見したが、私は得られた構造を処理する方法上の任意の情報を見つけるように見えることができますか?

ソースファイルは、結果のクエリ方法についてzip-query.cljを参照していますが、これも欠落しているようです。

+2

zip-query.cljの例は、clojure.data.zipのgithubリポジトリのsrc/test/clojure/clojure/data/zipにあるxml_test.cljにあります。 –

+0

面白いですまあ、SOの最も有益な人からの素晴らしい答えを得ました。しかし、結果の解析されたデータを実行した後でさえも。xmlのいずれかの提案を介して、結果の構造はまだ私に多くの意味をしません。 data.xmlがその後継者でない限り、XML-ZIPを見るつもりです。 – octopusgrabbus

答えて

81

はあなたのファイルで解析するには、次のXMLがあるとします。

<high-node> 
    <low-node>my text</low-node> 
</high-node> 

あなたがclojure.xmlをロード:

{:tag :high-node, :attrs nil, :content [{:tag :low-node, :attrs nil, :content ["my text"]}]} 
:解析されたときに

user=> (use 'clojure.xml) 

を、XMLは次のような構造を持っています

そしてファイルの内容をseqでthの内容を得ることができます電子low-node

user=> (for [x (xml-seq 
       (parse (java.io.File. file))) 
       :when (= :low-node (:tag x))] 
     (first (:content x))) 

("my text") 

あなたは、低ノードに関する情報のリスト全体へのアクセス権を持っていると思った場合は同様に、あなたは(= (:high-node (:tag x))):when述語を変更します

user=> (for [x (xml-seq 
       (parse (java.io.File. file))) 
       :when (= :high-node (:tag x))] 
     (first (:content x))) 

({:tag :low-node, :attrs nil, :content ["my text"]}) 

この作品のキーワード理由機能として動作することができる。 Questions about lists and other stuff in ClojureData Structures: Keywords

+0

優秀な回答! –

+0

非常に良い説明!私はこれを試してみるつもりです。 – Ralph

+0

(免責事項:私はclojure newbです)...しかし、これはREPLで私のために働いていましたが、私はそれをファイルで動作させることができませんでした(私の無知は責めることです)。 clojure.data.zip.xmlは変更なしで私のために働いていました。 – wonderfulthunk

52

上記の答えは作品を参照してください、私はそれが非常に簡単clojure.data.zip.xmlを使用することを見つける(Clojureの1.3より前clojure-contrib.zip-filter.xmlにするために使用)。

ファイル:

myfile.xml

<songs> 
    <track id="t1"><name>Track one</name></track> 
    <track id="t2"><name>Track two</name></track> 
</songs> 

コード:

; Clojure 1.3 
(ns example 
    (:use [clojure.data.zip.xml :only (attr text xml->)]) ; dep: see below 
    (:require [clojure.xml :as xml] 
      [clojure.zip :as zip])) 

(def xml (xml/parse "myfile.xml")) 
(def zipped (zip/xml-zip xml)) 
(xml-> zipped :track :name text)  ; ("Track one" "Track two") 
(xml-> zipped :track (attr :id))  ; ("t1" "t2") 

は残念ながら、あなたは、この素敵な読み取り/フィルタ機能を得るためにdata.zipへの依存にプルする必要があります。 それはleinに依存:)価値は、それは(17-8月-2013のような)のようになります。

[org.clojure/data.zip "0.1.1"] 

そしてdata.zip.xmlのためのドキュメント用として...私はちょうどに比較的小さなソースファイルhereを見て可能なことを見てください。もう1つの良い答えはhereです。

+2

これは私が取り組んでいるプロジェクトで私にとって素晴らしい仕事でした。 – wonderfulthunk

+1

(xml-> zipped:track:name text)は動作しますが、(xml-> zipped:songs:track:name text)は動作しませんか、(xml-> zipped:name text)は動作しません。タグの入れ子の特定のレベルを指定しなければならない理由はわかりませんが、他のタグは入れません。 –

+0

@RyanMooreジッパー(http://www.haskell.org/haskellwiki/Zipper)です。ジッパーは、現在のノードを持っているという点でコンテキスト感知であり、そのコンテキスト・ノードに対してトラバーサル命令を適切に渡す必要があります。どうやらデフォルトのコンテキストノードは理にかなっているrootです。 –