clojure.xml / parse: текстовые узлы только для пробелов игнорируются в смешанном контенте - PullRequest
1 голос
/ 05 июля 2011

Я новичок в clojure.xml и библиотеках Java XML в целом.

Я удивляюсь выводу clojure.xml / parse. Текстовые узлы, состоящие только из пробелов, игнорируются. Это может быть правильным в узле только для элемента, если было объявление DOCTYPE о том, что элемент не может иметь PCDATA, но пробел удаляется без DOCTYPES и даже в узлах со смешанным содержимым, , который не может иметь игнорируемые пробелы.

test.clj:

(require '[clojure.xml :as x])

(prn (x/parse "test.xml"))

test.xml:

<?xml version="1.0"?>
<x>

<y><z>AAA</z> BBB <z>AAA</z> <z>AAA</z></y>

</x>
Вывод

(отсутствует текстовый узел между <z>AAA</z> и <z>AAA</z>):

{:tag :x, :attrs {:xml:space "preserve"}, :content
  [{:tag :y, :attrs nil, :content
    [{:tag :z, :attrs nil, :content ["AAA"]}
     " BBB "
     {:tag :z, :attrs nil, :content ["AAA"]}
     {:tag :z, :attrs nil, :content ["AAA"]}]}]}

Я использую Clojure 1.2.0. Это ошибка, или это как-то так должно себя вести? (Даже добавление атрибута xml: space = "preserve" не работает.)

Спасибо за вашу помощь!

1 Ответ

2 голосов
/ 07 июля 2011

Это не ошибка. Я переставлю файл test.xml так, чтобы он выглядел как выход из файла test.clj:

<?xml version="1.0"?>
<x>

  <y>
    <z>AAA</z>
    BBB
    <z>AAA</z>
    <z>AAA</z>
  </y>

</x>

В этом файле «x» является корневым элементом, который содержит элемент «y», который содержит элементы «z» и «BBB» в виде строки. Вы можете посмотреть xml спецификацию о логической структуре XML-файла.

Возвращаясь к Clojure, Clojure использует SAX-парсер , основанный на управляемой событиями системе. Если вы знакомы с Java (что вы должны, если не знаете), попробуйте поиграть с «Образцом приложения SAX2» .

Это выходные данные «Образца приложения SAX2» с test.xml в качестве аргумента:

Start document
Start element: x
Characters:    "\n\n"
Start element: y
Start element: z
Characters:    "AAA"
End element: z
Characters:    " BBB "
Start element: z
Characters:    "AAA"
End element: z
Characters:    " "
Start element: z
Characters:    "AAA"
End element: z
End element: y
Characters:    "\n\n"
End element: x
End document

И копия вашего вывода test.clj:

{:tag :x, :attrs {:xml:space "preserve"}, :content
  [{:tag :y, :attrs nil, :content
    [{:tag :z, :attrs nil, :content ["AAA"]}
     " BBB "
     {:tag :z, :attrs nil, :content ["AAA"]}
     {:tag :z, :attrs nil, :content ["AAA"]}]}]}

Как видно clojure.xml/parse (из вывода test.clj) просто удаляет '\ n' (\ newline) и '' (\ space) элементы из документа xml, но другие элементы тот же самый. Если вам интересно, почему элементы отбрасываются, вы можете посмотреть clojure.xml / content-handler source и посмотреть на функцию push-chars:

push-chars (fn []
             (when (and (= *state* :chars)
                        (some (complement #(Character/isWhitespace (char %))) (str *sb*)))
               (set! *current* (push-content *current* (str *sb*)))))

И

user> (map (complement #(Character/isWhitespace (char %))) [\newline \space \a])
(false false true)

Обновление: если вы хотите сохранить пробелы, попробуйте упорядочить xml-файл следующим образом. (для меня это работает):

<?xml version="1.0" ?>
<x>

<y xml:space="preserve"><z>AAA</z> BBB <z>AAA</z> <z>AAA</z></y>

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