Обработка пространства имен в Groovys XmlSlurper
Ситуация:
def str = """
<foo xmlns:weird="http://localhost/">
<bar>sudo </bar>
<weird:bar>make me a sandwich!</weird:bar>
</foo>
"""
def xml = new XmlSlurper().parseText(str)
println xml.bar
Результат этого фрагмента
# sudo make me a sandwich!
Кажется, что парсер объединяет содержимое <bar>
и <weird:bar>
.
Желательно ли это поведение, и если да, то как я могу избежать этого и выбрать только <bar>
или <weird:bar>
?
Ответы
Ответ 1
По умолчанию XMLSlurper не является пространством имен. Это можно включить, объявив пространства имен с помощью declareNamespace
Method.
def str = """
<foo xmlns:weird="http://localhost/">
<bar>sudo </bar>
<weird:bar>make me a sandwich!</weird:bar>
</foo>
"""
def xml = new XmlSlurper().parseText(str).declareNamespace('weird':'http://localhost/')
println xml.bar // without namespace awareness, will print "sudo make me a sandwich!"
println xml.':bar' // will only print "sudo"
println xml.'weird:bar' // will only print "make me a sandwich!"
Вывод:
sudo make me a sandwich!
sudo
make me a sandwich!
Первый println
по-прежнему не будет содержать пространство имен. Второй println
будет печатать только тег без пространства имен. Если вы определили элемент с префиксом, указанным в третьем println
, вы получите только тег с именами.
Ответ 2
Я знаю, что это было дано некоторое время назад, но здесь альтернатива для всех, кто сталкивается с той же проблемой. Класс XmlSlurper
имеет три конструктора, пара из которых позволяет вам указать, что вы хотите, чтобы он был осведомлен о пространстве имен.
public XmlSlurper(boolean validating, boolean namespaceAware)
Объявите slurper, вызвав new XmlSlurper(false, true)
.
Надеюсь, это полезно для других.