كيف يمكنني طباعة عقدة رائعة مع الاحتفاظ بمساحة الاسم؟

StackOverflow https://stackoverflow.com/questions/227447

سؤال

عندما أستخدم هذا الرمز لإخراج بعض ملفات XML التي قمت بتحليلها (وتعديلها) باستخدامها 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()

لا تتم طباعة إعلانات مساحة الاسم على العقدة الجذرية، على الرغم من وجودها في toString() ل جذر...أيه أفكار؟

هل كانت مفيدة؟

المحلول

ويبدو انها denormalizing الانتاج وبما في ذلك السياق مساحة جنبا إلى جنب مع العقد التي تحتاج فعلا سياق مساحة الاسم.

وعلى سبيل المثال، صفحة ويب لهذا السؤال يأتي في مع المشاع الإبداعي مساحة جزءا لا يتجزأ من:

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

عند إخراج XML باستخدام هذا البرنامج النصي:

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

وينتهي تحريك مساحة الاسم إلى العقدة الترخيص التي يحتاج أن مساحة الاسم. لا صفقة ضخمة في هذه الحالة كما لا يوجد سوى عقدة واحدة في أن مساحة الاسم. إذا كانت namespaced معظم XML، فإنه على الأرجح تشعر بالانتفاخ الأمور أكثر قليلا جدا.

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

إذا أردت فعلا العقد تطبيع، وكنت قد لجعل بعض القرص إلى XmlNodePrinter للقيام 2 يمر من خلال XML، أول من جمع كل من مساحات الأسماء المستخدمة و2 إلى الناتج منها في الجزء العلوي بدلا من ضمن كل عقدة namespaced. رمز مصدر رائع هو في الواقع قراءة جميلة ولن يكون من الصعب أن تعديل إذا كنت بحاجة إلى هذا الواقع.

نصائح أخرى

لقد واجهت نفس المشكلة للتو وبعد قليل من العبث وجدت الحل البديل.

أنت تستخدم XmlSluper بدلا من ال XmlParser والاستخدام StreamingMarkupBuilder بدلاً من XmlNodePrinter.ثم يمكنك الاستفادة من الإغلاق في ربط واستخدام mkp متغير مدمج للإعلان عن مساحات الأسماء.

على سبيل المثال؛باستخدام مثال XML المصدر لـ Ted's من الأعلى:

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

النتائج في :

<?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>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top