Как объединить результаты запросов zip-фильтра в дереве XML в Clojure?

StackOverflow https://stackoverflow.com/questions/2057797

Вопрос

Я хочу объединить результаты трех запросов 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)!Может ли кто-нибудь указать, как я могу написать запрос, который объединит три других встроенных запроса?

Это было полезно?

Решение

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

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

Результат: («Фамилия А», «Фамилия Б, имя Б, суффикс Б»)

Другие советы

Я предполагаю, что альтернативное решение состоит в том, чтобы

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top