Domanda

Quando uso questo codice per generare un po 'di XML ho analizzato (e modificato) con XmlParser

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()

le dichiarazioni dello spazio dei nomi sul nodo radice non vengono stampate, anche se sono presenti nel toString () di root ... qualche idea?

È stato utile?

Soluzione

Sembra che stia denormalizzando l'output e includendo il contesto dello spazio dei nomi insieme ai nodi che hanno effettivamente bisogno del contesto dello spazio dei nomi.

Ad esempio, la pagina web per questa domanda arriva con lo spazio dei nomi creativeCommons incorporato:

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

Quando si genera l'xml usando questo script:

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

Finisce per spostare lo spazio dei nomi nel nodo di licenza che necessita di quello spazio dei nomi. Non è un grosso problema in questo caso in quanto esiste solo un singolo nodo in quello spazio dei nomi. Se la maggior parte dell'XML fosse spaziata dal nome, probabilmente farebbe gonfiare le cose un po 'di più.

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

Se davvero volessi normalizzare i nodi, dovresti apportare alcune modifiche a XmlNodePrinter per fare 2 passaggi attraverso l'XML, prima per raccogliere tutti gli spazi dei nomi usati e in secondo luogo per visualizzarli in alto anziché all'interno di ciascuno nodo con spazio dei nomi. Il codice sorgente groovy è in realtà abbastanza leggibile e non sarebbe così difficile da modificare se ne avessi davvero bisogno.

Altri suggerimenti

Ho appena avuto lo stesso problema e dopo un po 'di armeggiare ho trovato una soluzione alternativa.

Usi XmlSluper invece di XmlParser e usi StreamingMarkupBuilder anziché XmlNodePrinter . Quindi approfitti della chiusura in bind e usi la variabile incorporata mkp per dichiarare gli spazi dei nomi.

Ad esempio; usando l'esempio xml di origine di Ted dall'alto:

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

Risultati in:

<?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>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top