Это не ошибка. Я переставлю файл 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>