2008-10-22 3 views
4

Lorsque j'utilise ce code pour la sortie du XML I analysables (et modifié) avec XmlParserComment imprimer un nœud groovy avec un espace de noms préservé?

XmlParser parser = new XmlParser() 
def root = parser.parseText(feedUrl.toURL().text) 
def writer = new StringWriter() 
new XmlNodePrinter(new PrintWriter(writer)).print(root) 
println writer.toString() 

les déclarations d'espace de noms sur le nœud racine ne sont pas imprimés, même si elles sont là dans le toString() de racine ... des idées?

Répondre

1

Il semble que ce soit la dénormalisation de la sortie et l'inclusion du contexte de l'espace de nommage avec les nœuds qui ont réellement besoin du contexte de l'espace de nommage.

Par exemple, la page web pour cette question vient avec espace de noms CreativeCommons embarqué:

<feed xmlns="http://www.w3.org/2005/Atom" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:thr="http://purl.org/syndication/thread/1.0"> 
    <!-- snip --> 
    <creativeCommons:license>http://www.creativecommons.org/licenses/by-nc/2.5/rdf</creativeCommons:license> 
    <!-- snip --> 
</feed> 

Lorsque vous la sortie du XML en utilisant ce script:

def root = new XmlParser().parseText("http://stackoverflow.com/feeds/question/227447".toURL().text) 
println new XmlNodePrinter().print(root) 

Il finit par déplacer l'espace de noms à la nœud de licence qui a besoin de cet espace de noms. Pas un gros problème dans ce cas car il n'y a qu'un seul nœud dans cet espace de noms. Si la plus grande partie du XML avait un espace de noms, cela gonflerait probablement un peu plus les choses.

<feed xmlns="http://www.w3.org/2005/Atom"> 
    <!-- snip --> 
    <creativeCommons:license xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule"> 
http://www.creativecommons.org/licenses/by-nc/2.5/rdf 
    </creativeCommons:license> 
    <!-- snip --> 
</feed> 

Si vous voulez réellement les noeuds normalisés, vous auriez à faire quelques modifications à la XmlNodePrinter faire 2 passe à travers le XML, d'abord de rassembler tous les espaces de noms utilisés et 2 pour les sorties en haut plutôt que dans chaque nœud avec un espace de noms. Le code source groovy est en fait assez lisible et ne serait pas si difficile à modifier si vous en aviez réellement besoin.

3

Je viens d'avoir le même problème et après un peu de fiddling j'ai trouvé une solution de contournement.

Vous utilisez le XmlSluper au lieu du XmlParser et utiliser StreamingMarkupBuilder au lieu de XmlNodePrinter. Ensuite, vous tirer parti de la fermeture dans lier et utiliser la variable intégrée mkp pour déclarer les espaces de noms.

Par exemple; en utilisant l'exemple xml source de Ted en haut:

def root = new XmlSlurper().parseText("http://stackoverflow.com/feeds/question/227447".toURL().text)) 
def outputBuilder = new StreamingMarkupBuilder() 
String result = XmlUtil.serialize(outputBuilder.bind { 
    mkp.declareNamespace('':'http://www.w3.org/2005/Atom') 
    mkp.declareNamespace('creativeCommons':'http://backend.userland.com/creativeCommonsRssModule') 
    mkp.declareNamespace('re':'http://purl.org/atompub/rank/1.0') 
    mkp.yield root } 
) 
println result 

Résultats dans:

<?xml version="1.0" encoding="UTF-8"?><feed xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns="http://www.w3.org/2005/Atom" xmlns:re="http://purl.org/atompub/rank/1.0"> 
<title type="text">How do I print a groovy Node with namespace preserved? - Stack Overflow </title> 
<link rel="self" type="application/atom+xml" href="http://stackoverflow.com/feeds/question/227447"/> 
<link rel="alternate" type="text/html" href="http://stackoverflow.com/questions/227447"/> 
<subtitle>most recent 30 from stackoverflow.com</subtitle> 
<updated>2011-02-16T05:13:17Z</updated> 
<id>http://stackoverflow.com/feeds/question/227447</id> 
<creativeCommons:license>http://www.creativecommons.org/licenses/by-nc/2.5/rdf</creativeCommons:license> 
<entry> 
<id>http://stackoverflow.com/questions/227447/how-do-i-print-a-groovy-node-with-namespace-preserved</id> 
<re:rank scheme="http://stackoverflow.com">2</re:rank> 
Questions connexes