Как объединить результаты запросов zip-фильтра в дереве XML в Clojure? - PullRequest
8 голосов
/ 13 января 2010

Я хочу объединить результаты трех запросов zip-фильтра в дереве xml. XML, который я анализирую, выглядит так:

<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>

Из этого примера видно, что <given_name> и <suffix> являются необязательными - требуется только <surname>. Здесь кроется моя проблема - если я выполню три отдельных запроса, то ответы, которые я получу, будут разногласия друг с другом:

(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)

После выполнения этих трех запросов у меня останутся три последовательности, мощности которых не совпадают; given_name и suffix будут иметь длину 1, а surname будет иметь длину 2. Для меня невозможно объединить компоненты каждого имени. Мне нужно написать один запрос, который будет выполнять это объединение имен во время построения последовательности.

Я смотрю на очень скудную документацию для clojure.contrib.zip-filter.xml и не могу понять, как я мог это сделать (или, если это вообще возможно). К сожалению, я новичок Clojure (и Lisp)! Кто-нибудь может указать, как я могу написать запрос, который объединит три других встроенных запроса?

Ответы [ 2 ]

6 голосов
/ 14 января 2010

Вы можете получить все поддеревья человека за один шаг (xml-> xmlzip: публикация: contributors: person_name), затем получить части имени, если они существуют (xml1-> personzip: текст фамилии), и объединить их с желаемым результатом вот так:

(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)))

Результаты в ("Фамилия A" "Фамилия B, учитывая B, суффикс B")

2 голосов
/ 13 января 2010

Полагаю, альтернативным решением является

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

, а затем обрабатывать каждый <person_name>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...