2010-01-13 35 views
8

Tôi muốn kết hợp kết quả của ba truy vấn bộ lọc zip trên cây xml. XML Tôi đang phân tích cú pháp như sau:Làm cách nào để kết hợp các kết quả từ truy vấn bộ lọc zip trên cây xml trong Clojure?

<someroot> 
    <publication> 
    <contributors> 
     <person_name> 
     <surname>Surname A</surname> 
     </person_name> 
     <person_name> 
     <given_name>Given B</given_name> 
     <surname>Surname B</surname> 
     <suffix>Suffix B</suffix> 
     </person_name> 
    </contributors> 
    </publication> 
</someroot> 

Từ ví dụ này, bạn có thể thấy rằng <given_name><suffix> là không bắt buộc - chỉ <surname> là bắt buộc. Ở nằm vấn đề của tôi - nếu tôi chạy ba truy vấn riêng biệt các câu trả lời tôi nhận được sẽ được ra khỏi kilter với nhau:

(xml-> xml :publication :contributors :person_name :given_name text) 
(xml-> xml :publication :contributors :person_name :surname text) 
(xml-> xml :publication :contributors :person_name :suffix text) 

Sau khi chạy ba thắc mắc tôi sẽ bị bỏ lại với ba trình tự mà cardinalities không phù hợp; given_namesuffix sẽ có độ dài 1 trong khi surname sẽ có độ dài 2. Điều này khiến tôi không thể kết hợp các thành phần của từng tên. Tôi cần phải viết một truy vấn duy nhất sẽ thực hiện việc ghép nối tên này trong quá trình xây dựng chuỗi.

Tôi đang xem tài liệu rất thưa thớt cho clojure.contrib.zip-filter.xml và không thể tìm ra cách tôi có thể thực hiện việc này (hoặc nếu có thể). Thật không may tôi là một Clojure (và Lisp) newbie! Bất cứ ai có thể chỉ ra làm thế nào tôi có thể viết một truy vấn mà sẽ nối ba truy vấn nhúng khác?

+1

Kiểm tra này gần đây SO câu hỏi ra: http://stackoverflow.com/questions/2034550/return-multiple-values-using-clojure-xml-zipper –

Trả lời

6

Bạn có thể nhận tất cả các subtrees người trong một bước (xml-> xmlzip: publication: contributors: person_name), sau đó lấy các phần tên nếu chúng tồn tại (xml1-> personzip: họ) và kết hợp chúng với kết quả bạn muốn như vậy:

(use 'clojure.contrib.zip-filter.xml) 
(defn format-name 
    [surname given suffix] 
    (str surname (if given (str ", " given)) (if suffix (str ", " suffix)))) 
(defn get-names 
    [xz] 
    (map (juxt 
     #(xml1-> % :surname text) 
     #(xml1-> % :given_name text) 
     #(xml1-> % :suffix text)) 
    (xml-> xz :publication :contributors :person_name))) 
(let [x (clojure.zip/xml-zip (clojure.xml/parse "foo.xml"))] 
    (map (partial apply format-name) (get-names x))) 

Kết quả trong ("Surname A" "Họ B, Do B, Suffix B")

2

Tôi cho rằng một giải pháp thay thế là

(xml-> xml :publication :contributors :person_name) 

và sau đó xử lý mỗi <person_name> sau này.

Các vấn đề liên quan