Frage

Wenn ich diesen Code zur Ausgabe einig XML I analysiert (und modifizierte) mit 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()

die Namespace-Deklarationen auf den Wurzelknoten nicht gedruckt werden, obwohl sie in der toString() der es root ... irgendwelche Ideen?

War es hilfreich?

Lösung

Es sieht aus wie es die Ausgabe des Denormalisierung und einschließlich des Namespace-Kontext mit den Knoten zusammen, die den Namespace-Kontext tatsächlich benötigen.

Zum Beispiel für diese Frage die Webseite kommt mit Creativenamensraum eingebettet:

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

Wenn Sie die Ausgabe der XML mit diesem Skript:

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

Es endet den Namespace auf den Lizenzknoten, das diesen Namensraum benötigt. Keine große Sache in diesem Fall, da es in diesem Namensraum nur ein einzelner Knoten ist. Wenn die meisten der XML-Namespace wurden, würde es wahrscheinlich Dinge aufblasen ein bisschen mehr.

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

Wenn Sie wollten eigentlich die Knoten normalisiert, würden Sie einige kleine Änderungen an der XmlNodePrinter machen müssen zwei Durchgänge durch die XML zu tun, zunächst alle verwendeten Namensräume und 2. die Ausgabe sammeln sie an der Spitze, anstatt in jedem Namensraum-Knoten. Der groovy Quellcode ist eigentlich ziemlich lesbar und wäre nicht so schwer zu ändern, wenn Sie diese tatsächlich benötigt wird.

Andere Tipps

Ich habe gerade das gleiche Problem und nach ein wenig das Hantieren Ich habe eine Abhilfe gefunden.

Mit der XmlSluper statt XmlParser und verwenden StreamingMarkupBuilder statt XmlNodePrinter . Dann nehmen Sie die Vorteile der Schließung in bind und die mkp integrierte Variable die Namensräume zu erklären.

Zum Beispiel; unter Verwendung des XML-Quell Beispiel von Teds von oben:

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

Ergebnisse 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>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top