2011-12-29 7 views
10

La situación Espacio de nombres:manejo en 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 

La salida de este fragmento es

# sudo make me a sandwich! 

Parece que el analizador se fusiona el contenido de <bar> y <weird:bar>.

Se desea este comportamiento y, en caso afirmativo, ¿cómo puedo evitar esto y seleccionar solo <bar> o <weird:bar>?

Respuesta

17

De forma predeterminada, XMLSlurper no tiene en cuenta el espacio de nombres. Esto puede activarse declarando espacios de nombres con declareNamespaceMethod.

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!" 

La salida es:

sudo make me a sandwich! 
sudo 
make me a sandwich! 

La primera println sigue sin ser consciente de espacio de nombres. El segundo println solo imprimirá la etiqueta sin espacio de nombre. Si califica el elemento con el prefijo que se muestra en el tercer println, solo obtiene la etiqueta de espacio de nombre.

+1

Gracias, eso explica algunas cosas :) Estoy analizando diferentes xmls y no sé qué espacios de nombres están usando; ¿hay alguna posibilidad de lograr la salida de 'println xml. ': bar'' además de analizar el elemento raíz para los espacios de nombres y declararlos? – codeporn

+0

Creo que XmlSlurper es consciente del espacio de nombres de forma predeterminada, ya que 'new XmlSlurper() -> new XmlSlurper (falso, verdadero)': http://stackoverflow.com/questions/33418826/are-xmlparser-and-xmlslurper-namespace- aware-by-default – jalopaba

+0

Ugh. Por alguna razón, esto no funciona para mí. Estoy analizando un documento RSS con espacios de nombres declarados en los encabezados. Puedo acceder a rss.channel.link pero rss.channel.'atom: link'.text() y rss.channel.'atom: link '. @ Href.text() todos devuelven valores en blanco. :( – Umopepisdn

2

Sé que esto fue respondido hace un tiempo, pero aquí hay una alternativa para cualquier persona que tenga el mismo problema. La clase XmlSlurper tiene tres constructores, a couple of which le permiten especificar que desea que tenga en cuenta el espacio de nombres.

public XmlSlurper(boolean validating, boolean namespaceAware) 

Declare el slurper llamando al new XmlSlurper(false, true). Espero que esto sea útil para otros.