Как распечатать заводной узел с сохраненным пространством имен?

Когда я использую этот код для вывода некоторого 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() в root ... есть идеи?

4 голоса | спросил danb 23 +04002008-10-23T00:35:41+04:00312008bEurope/MoscowThu, 23 Oct 2008 00:35:41 +0400 2008, 00:35:41

2 ответа


0

Похоже, что он денормализует вывод и включает в себя контекст пространства имен вместе с узлами, которым на самом деле нужен контекст пространства имен.

Например, веб-страница для этого вопроса имеет встроенное пространство имен creativeCommons:

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

В итоге происходит перемещение пространства имен к узлу лицензии, которому необходимо это пространство имен. В этом случае не так уж и много, поскольку в этом пространстве имен только один узел. Если бы большая часть 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-й - вывести их сверху, а не внутри Пространство имен Отличный исходный код на самом деле довольно читабелен и его не так сложно изменить, если вам это действительно нужно.

ответил Ted Naleid 23 +04002008-10-23T08:55:15+04:00312008bEurope/MoscowThu, 23 Oct 2008 08:55:15 +0400 2008, 08:55:15
0

У меня только что возникла та же проблема, и после небольшого перебора я нашел обходной путь.

Вместо XmlParser вы используете StreamingMarkupBuilder XmlSluper em> вместо XmlNodePrinter . Затем вы используете закрытие в bind и используете встроенную переменную mkp для объявления пространств имен.

Например; используя исходный XML-пример Теда сверху:

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>
ответил Damo 16 FebruaryEurope/MoscowbWed, 16 Feb 2011 08:25:26 +0300000000amWed, 16 Feb 2011 08:25:26 +030011 2011, 08:25:26

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132