Groovy StreamingMarkupBuilder()生成非XML

时间:2012-05-06 03:17:51

标签: java xml grails groovy

我试图弄清楚为什么在某些情况下StreamingMarkupBuilder()会产生非XML。这是我如何称呼它:

public static void saveXMLToFile(def document, String file) {
    def xmlBuilder = new StreamingMarkupBuilder().bind {
        mkp.xmlDeclaration()
        mkp.yield document
    }
    new File(file).withWriter { out ->
        out << xmlBuilder
    }
}

以下是我们如何到达那里:

def document = new XmlParser(false, false).parse(manuscriptFile)
if (document.name().equals("appendix")) {
    def newNode = new groovy.util.Node(null, "chapter", document.attributes(), 
                                       document.value())
    XMLUtils.saveXMLToFile(newNode, manuscriptFile)
}

但是我没有拿出XML,而是:

<?xml version='1.0'?>
title[attributes={id=_2140_5145_361}; value=[An introduction to blah]]partintro
[attributes={id=_2140_5145_362}; value=[para[attributes={id=_2140_5145_363}; value=[My 
contents, blah blah blah]]]

我已经尝试过这些文档,但不幸的是我对Groovy的态度并不高,所以我确信我错过了一些简单的东西。 :(

提前致谢...

1 个答案:

答案 0 :(得分:7)

最简单的方法是使用XmlUtil类,遗憾的是,这个类没有很好的记录:

def saveXMLToFile(Node document, String file) {
    new File(file).withWriter { out ->
        XmlUtil.serialize(document, out)
    }
}

(注意我更改了方法签名以接收节点)

我发现的问题是groovy.xml.MarkupBuilder(或StreamingMarkupBuilder)和groovy.util.Node, MarkupBuilder返回,似乎并没有相处得很好。至少我找不到将XML声明添加到Node的方法,然后可以用XmlNodePrinter打印;或者在MarkupBuilder闭包中添加一个Node,我猜这应该是可能/容易的。如果有人知道如何做这些,请在评论中告诉它或添加新答案= D

所以我能找到的第二个最简单的解决方案,不依赖于XmlUtil的文档记录不足,首先使用StreamingMarkupBuilder打印XML声明(甚至不是MarkupBuilder,因为它似乎需要根节点声明,我们不需要我希望在这种情况下)然后使用XmlNodePrinter打印文档:

def saveXMLToFile(Node document, String file) {
    new File(file).withWriter { out ->
        out << new StreamingMarkupBuilder().bind { mkp.xmlDeclaration() }
        new XmlNodePrinter(new PrintWriter(out)).print(document)
    }
}