Vra

Wanneer ek gebruik hierdie kode om afvoer sommige XML ek ontleed (en aangepas) met 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 verklarings op die wortel node is nie gedruk, selfs al is hulle daar in die toString() van wortel ... enige idees?

Was dit nuttig?

Oplossing

Dit lyk asof dit denormalizing die uitset en met die naamruimte konteks saam met die knope wat eintlik die naamruimte konteks nodig.

Byvoorbeeld, die webblad vir hierdie vraag kom in met creative naamruimte ingesluit:

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

As jy uitset die xml die gebruik van hierdie script:

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

Dit eindig die verskuiwing van die naamruimte om die lisensie node dat naamruimte nodig. Nie 'n groot deal in hierdie geval as daar net 'n enkele nodus in daardie naamruimte. As die meeste van die XML is namespaced, sal dit waarskynlik opblaas dinge nogal 'n bietjie meer.

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

As jy eintlik wou die nodes genormaliseer, jy wil hê om 'n paar tweaks maak om die XmlNodePrinter tot 2 passe doen deur die XML, eers na al die gebruik naamruimtes en 2 bymekaar om uitset van hulle by die top eerder as binne elke namespaced node. Die groovy bronkode is eintlik redelik leesbare en sou nie so moeilik om te verander as jy dit werklik nodig is.

Ander wenke

Ek het net het dieselfde probleem en na 'n bietjie van fiddling ek 'n oplossing gevind het.

Jy gebruik die XmlSluper in plaas van die XmlParser en gebruik StreamingMarkupBuilder in plaas van XmlNodePrinter . Dan voordeel van die sluiting neem jy in bind en gebruik die MKP ingeboude veranderlike om die naamruimtes verklaar.

Byvoorbeeld, gebruik van die bron xml voorbeeld van Ted se van bo:

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

Resultate 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>
Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top