Синтаксический анализ XML с помощью clojure.data.xml.Как опустить элементы "\ n" из: содержимого во время "разбора" - PullRequest
0 голосов
/ 24 апреля 2019

Сначала я проанализировал XML-файл как

(def xtest (slurp "./resources/smallXMLTest.xml"))
(def way1 (clojure.xml/parse))
(:content way1)

И НЕ иметь элементов "\ n" в :content хэш-карте.

Но когда я анализирую XML вот так, с помощью clojure.data.xml

(def fr
 (-> filename
     io/file
     io/input-stream
     io/reader))

(def fileAsStream (fr XMLfilePath))

(def way2 (clojure.data.xml/parse fileAsStream))

затем я получил строки "\ n" в каждом неконечном :content элементе в way2 var, между каждой парой внутренних элементов XMLElements: (*

Есть ли способ избежать этих "\ n" строк?

1 Ответ

3 голосов
/ 24 апреля 2019

Недавно я добавил 2 синтаксических анализатора XML в библиотеку Tupelo , один из которых основан на clojure.data.xml, а другой - tagsoup.В обоих случаях я удаляю пробельные узлы по умолчанию.Вот оперативная функция :

(defn enlive-remove-whitespace
  "Removes whilespace strings from Enlive data :content vectors."
  [item]
  (if (and (map? item) ; Enlive data parsed from XML may has raw strings (esp. whitespace) embedded in it
        (contains-key? item :tag)) ; when parsing html, may get non-enlive nodes like {:type :comment, :data "..."}
    (let [content-new (cond-it-> (:content item)
                        (or (nil? it) (empty? it)) []
                        :then (drop-if (fn [arg]
                                         (and (string? arg)
                                           (ts/whitespace? arg))) it)
                        :then (mapv enlive-remove-whitespace it))]
      (glue item {:content content-new}))
    item))

Используется так для tupelo.parse.xml:

(s/defn parse       ; #todo fix docstring
  ([xml-input] (parse xml-input sax-parse-fn))
  ([xml-input parse-fn]
    (enlive-remove-whitespace
      (enlive-normalize
        (parse-raw xml-input parse-fn)))))

Итак, вы видите, что вы можете использовать Функция parse-raw, если вы не хотите нормализовать или обрезать пробелы в результирующих данных в формате Enlive.

Доступны аналогичные варианты для parse и parse-rawв пространстве имен tupelo.parse.tagsoup.

Примеры использования можно увидеть в тесте ns :

(def xml-str "<foo>
                <name>John</name>
                <address>1 hacker way</address>
                <phone></phone>
                <school>
                    <name>Joe</name>
                    <state>CA</state>
                    <type>FOOBAR</type>
                </school>
                <college>
                    <name>mit</name>
                    <address></address>
                    <state>Denial</state>
                </college>
              </foo> ")

(def enlive-tree-normalized-nonblank
  {:tag     :foo,
   :attrs   {},
   :content [{:tag :name, :attrs {}, :content ["John"]}
             {:tag :address, :attrs {}, :content ["1 hacker way"]}
             {:tag :phone, :attrs {}, :content []}
             {:tag     :school,
              :attrs   {},
              :content [{:tag :name, :attrs {}, :content ["Joe"]}
                        {:tag :state, :attrs {}, :content ["CA"]}
                        {:tag :type, :attrs {}, :content ["FOOBAR"]}]}
             {:tag     :college,
              :attrs   {},
              :content [{:tag :name, :attrs {}, :content ["mit"]}
                        {:tag :address, :attrs {}, :content []}
                        {:tag :state, :attrs {}, :content ["Denial"]}]}]})

с результатом

(dotest  
  (let [xml-data              (xml/parse     (ts/string->stream xml-str))
        tagsoup-data          (tagsoup/parse (ts/string->stream xml-str))]
    (is= enlive-tree-normalized-nonblank xml-data)
    (is= enlive-tree-normalized-nonblank tagsoup-data) ))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...